如何在C中动态地在数组的最后位置插入元素?

问题描述 投票:0回答:4

我是C中的新手,并尝试在C中的最后一个位置插入数字,以使数组的大小随时间变化。

第一个数组是这样的:

temp[10] = {1, 2, 0, 0, 5, 6, 0, 8, 0, 0};

现在我们如何将temp中的那些值!= 0插入到定义长度为5的新数组中:tmp

这是我正在尝试的内容:

void push(int arr[], int value, int current){
  arr[current] = value;
}

int main(void) { 

  int temp[10] = {1, 2, 0, 0, 5, 6, 0, 8, 0, 0};
  int tmp[5];

  for(int i=0;;i++){
    if(temp[i]) push(tmp, temp[i],sizeof(tmp)/sizeof(tmp[0]));
    // I don't put i < 10 int the loop initialization. Since the tmp's length is just 5

  }
  // I put sizeof(tmp)/sizeof(tmp[0]) there because we want at every time the tmp is inserted a new value,
  // it's length will change (increase by 1). 
  // So next loop round, the new value will be added to the last position
  // But I failed to do so

} 

当前输出

exited segmentation fault
// I'd be very grateful if someone can also explain for me why this error happens

所需的输出

tmp[5] = {1, 2, 5, 6, 8}
c arrays dynamic-memory-allocation
4个回答
0
投票

您对push的定义要求第3个参数为放置元素的位置。但是,表达式sizeof(tmp)/sizeof(tmp[0])提供了数组的size,因此它将通过数组的最后一个元素进行索引(因为C中的索引来自0..n-1)。这本身可能会导致分段错误。

您也没有为循环提供终止条件。它将永远持续下去。

您的解决方案可能只是:

for(int i=0, j=0; i<10; i++)
   if(temp[i]) push(tmp, temp[i], j++);

0
投票

什么是

试图在C的最后一个位置插入数字

尽管您得到了[[David Ranieri的解释性回答,但我想展示最简单的方法,同时请记住您是新手。看下面的代码:-

代码:

#include <stdio.h> #include <stdlib.h> #define SIZE 10 void push(int arr[], int value, int current){ arr[current] = value; } int main(void) { int temp[SIZE] = {1, 2, 0, 0, 5, 6, 0, 8, 0, 0}; int *tmp = NULL, count = 0, i, j; // Loop for counting non-zero values in temp array. for (i = 0; i < SIZE; ++i) if (temp[i]) count++; // Dynamically allocating space for tmp along with checking errors if any. if((tmp = (int *)malloc(count * sizeof(int))) == NULL) { printf("Memory Not Available.\n"); exit(-1); } for(i = 0, j = 0; i < SIZE; i++){ if(temp[i]) push(tmp, temp[i], j++); } // Printing your desired output. for(i = 0; i < count; ++i) printf("%d\t", tmp[i]); free(tmp); }
此处tmp的大小将根据temp的非零元素而变化。现在,如果要使temp数组成为动态数组,请使用与tmp相同的方法,只需在运行时要求用户输入temp的大小,然后再输入其元素/值。 

0
投票
问题是您正在访问temp的边界之外,因为您没有指定何时在循环中停止。

对于动态数组,当您不知道前面的元素数时,可以使用realloc

#include <stdio.h> #include <stdlib.h> void push(int **arr, size_t *size, int value) { int *ptr = realloc(*arr, sizeof(*ptr) * (*size + 1)); if (ptr == NULL) { free(*arr); perror("push"); exit(EXIT_FAILURE); } ptr[*size] = value; *size += 1; *arr = ptr; } int main(void) { int temp[10] = {1, 2, 0, 0, 5, 6, 0, 8, 0, 0}; int *arr = NULL; size_t size = 0; for (size_t i = 0; i < sizeof temp / sizeof temp[0]; i++) { if (temp[i]) { push(&arr, &size, temp[i]); } } for (size_t i = 0; i < size; i++) { printf("%d\n", arr[i]); } free(arr); }

请注意,即使它说明了使用可增长数组,该示例也被认为是不好的代码,但更健壮的设计将照顾到大小,并能够自行管理分配和释放:

#include <stdio.h> #include <stdlib.h> typedef struct { int *data; size_t size; } dyn_array; dyn_array *create_dyn_array(void) { dyn_array *arr = calloc(1, sizeof *arr); if (arr == NULL) { perror("create_dyn_array"); exit(EXIT_FAILURE); } return arr; } void destroy_dyn_array(dyn_array *arr) { free(arr->data); free(arr); } void push_dyn_array(dyn_array *arr, int value) { int *ptr = realloc(arr->data, sizeof(*ptr) * (arr->size + 1)); if (ptr == NULL) { destroy_dyn_array(arr); perror("push_dyn_array"); exit(EXIT_FAILURE); } ptr[arr->size++] = value; arr->data = ptr; } int main(void) { int temp[10] = {1, 2, 0, 0, 5, 6, 0, 8, 0, 0}; dyn_array *arr = create_dyn_array(); for (size_t i = 0; i < sizeof temp / sizeof temp[0]; i++) { if (temp[i]) { push_dyn_array(arr, temp[i]); } } for (size_t i = 0; i < arr->size; i++) { printf("%d\n", arr->data[i]); } destroy_dyn_array(arr); }

这更好,但仍不完美,因为我们限于固定类型(int),通过增加一些内存,我们可以调整代码以支持任何类型(使用通用类型void *)作为优化。 ,动态数组将增长2倍,而不是每次迭代都调用realloc

#include <stdio.h> #include <stdlib.h> /* Begin - This API is supposed to be in a header */ typedef struct { void **data; size_t room; size_t size; } dynarray; dynarray *dynarray_create(void) { dynarray *array = calloc(1, sizeof *array); if (array == NULL) { return NULL; } array->data = malloc(sizeof(void *)); if (array->data == NULL) { free(array); return NULL; } array->room = 1; return array; } void *dynarray_push(dynarray *array, void *data) { if (data == NULL) { return NULL; } if (array->size == array->room) { array->room *= 2; void *ptr = realloc(array->data, array->room * sizeof(void *)); if (ptr == NULL) { return NULL; } array->data = ptr; } array->data[array->size++] = data; return data; } void *dynarray_get(dynarray *array, size_t index) { return array->data[index]; } size_t dynarray_size(dynarray *array) { return array->size; } void dynarray_destroy(dynarray *array, void (*func)(void *data)) { if (func != NULL) { for (size_t i = 0; i < array->size; i++) { func(array->data[i]); } } free(array->data); free(array); } /* End API */ int main(void) { int temp[10] = {1, 2, 0, 0, 5, 6, 0, 8, 0, 0}; dynarray *array = dynarray_create(); if (array == NULL) { perror("dynarray_create"); exit(EXIT_FAILURE); } for (size_t i = 0; i < sizeof temp / sizeof temp[0]; i++) { if (temp[i]) { if (dynarray_push(array, &temp[i]) == NULL) { perror("dynarray_push"); exit(EXIT_FAILURE); } } } size_t size = dynarray_size(array); for (size_t i = 0; i < size; i++) { int *data = dynarray_get(array, i); printf("%d\n", *data); } dynarray_destroy(array, NULL); }


0
投票
C没有动态数组。数组具有根据其定义确定的固定大小。您可以使用malloc()分配对象,它们的行为类似于数组,但是必须分别跟踪其分配的大小。追加元素需要重新分配数组,以便其在内存中的地址可能会更改。

在您的代码中,tmp的固定大小为5个元素。您可以维护一个索引,以指定要使用的元素数量,并在push函数中对其进行更新:

#include <stdio.h> int push(int arr[], int value, size_t size, size_t *current) { if (*current < size) { arr[(*current)++] = value; return 0; } else { /* array is full */ return -1; } } int main(void) { int temp[10] = { 1, 2, 0, 0, 5, 6, 0, 8, 0, 0 }; int tmp[5]; size_t pos = 0; for (size_t i = 0; i < sizeof(temp) / sizeof(temp[0]); i++) { if (temp[i]) push(tmp, temp[i], sizeof(tmp) / sizeof(tmp[0]), &pos); } printf("tmp:"); for (size_t i = 0; i < pos; i++) { printf(" %d", tmp[i]); } printf("\n"); return 0; }

© www.soinside.com 2019 - 2024. All rights reserved.