我试图使一个数组的简单例子,增加其输入。输入是一串数字,这个数列的末尾是0。我想到的是每次读取新数字时增加我的数组,但由于某种原因,这似乎不起作用,因为我得到一个错误:
Realloc(): invalid pointer
这是我当前的代码:
#include <stdio.h>
#include <stdlib.h>
int *resizeIntArray(int *series, int newSize) {
int *newSeries = realloc(series, newSize * sizeof(int));
if (newSeries == NULL) {
printf("Error: Memory allocation failed");
exit(-1);
}
return newSeries;
}
int main(int argc, char *argv[]) {
int number;
scanf("%d", &number);
int *numbers;
int size = 0;
while (number != 0) {
numbers = resizeIntArray(numbers, size + 1);
printf("%d ", number);
scanf("%d", &number);
size++;
}
}
你正在传递一个未初始化的变量给你的函数,然后传递给realloc
,它需要一个指向先前分配的内存的指针,或者NULL
。
初始化变量:
int *numbers = NULL;
你的代码中有多个问题:
- 您没有将
numbers
初始化为NULL
,因此realloc()
在第一次调用时调用未定义行为。 - 不检查
scanf()
的返回值,如果输入流不包含0
号码,则可能导致无限循环和未定义行为。 - 你没有释放数组(次要)。
- 你没有在
main()
(minor)的末尾返回0。
这里有一个更简单、更安全的版本:
#include <stdio.h>
#include <stdlib.h>
int *resizeIntArray(int *series, int newSize) {
int *newSeries = realloc(series, newSize * sizeof(int));
if (newSeries == NULL) {
printf("Error: Memory allocation failed");
exit(-1);
}
return newSeries;
}
int main(int argc, char *argv[]) {
int number;
int *numbers = NULL;
int i, size = 0;
/* reading the numbers */
while (scanf("%d", &number) == 1 && number != 0) {
numbers = resizeIntArray(numbers, size + 1);
numbers[size++] = number;
}
/* printing the numbers */
for (i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("n");
free(numbers);
return 0;
}
您可以尝试这样的方法。这包括:
- 内存检查,带有适当的错误消息。
- 使用
malloc()
和realloc()
来分配和重新分配内存。 - 在运行时分配足够的空间。
- 适当检查
scanf()
的返回值。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#define EXIT 0
void exit_if_null(void *ptr, const char *msg);
int
main(int argc, char const *argv[]) {
int *numbers = NULL;
int number, num_size = 1, count = 0, i;
/* initial allocation of memory */
numbers = malloc(num_size * sizeof(*numbers));
/* small error checking, to be safe */
exit_if_null(numbers, "Initial Allocation");
/* Reading in numbers */
printf("Enter numbers(0 to end): ");
while (scanf("%d", &number) == 1 && number != EXIT) {
/* valid number found, but is there space? */
if (num_size == count) {
num_size *= 2;
/* resize run-time array */
numbers = realloc(numbers, num_size * sizeof(*numbers));
exit_if_null(numbers, "Reallocation");
}
numbers[count++] = number;
}
/* print out numbers */
printf("Your numbers stored in array:n");
for (i = 0; i < count; i++) {
printf("%d ", numbers[i]);
}
/* free allocated memory, very important */
free(numbers);
return 0;
}
/* helper function for error checking */
void
exit_if_null(void *ptr, const char *msg) {
if (!ptr) {
printf("Unexpected null pointer: %sn", msg);
exit(EXIT_FAILURE);
}
}
首先,在重新分配内存之前应该先分配一些内存。因此,您的代码将更改为:
#include <stdio.h>
#include <stdlib.h>
int *resizeIntArray(int *series, int newSize){
int *newSeries = realloc(series,newSize*sizeof(int));
if(newSeries == NULL){
printf("Error: Memory allocation failed");
exit(-1);
}
return newSeries;
}
int main(int argc, char* argv[]) {
int number;
scanf("%d",&number);
int *numbers=malloc(sizeof(int));///CHANGED
int size = 1;///CHANGED
while(number != 0){
numbers = resizeIntArray(numbers,size +1);
printf("%d ",number);
scanf("%d",&number);
size++;
}
}
但是你所做的是很没有效率的。realloc()函数隐藏了free()、malloc()和最糟糕的memcpy()。所以如果你在每个新项目上都使用realloc(),你将会有一段糟糕的时间…O (n ^ 2)。最好的方法是分配一个内存缓冲区:
struct vector
{
int *numbers;
size_t size;
size_t i;
}
#define DEFAULTBUF 100
int main()
{
struct vector v;
v.numbers=malloc(sizeof(int)*DEFAULTBUF);
v.size=DEFAULTBUF;
v.i=0;
scanf("%d",&number);
while(number != 0 && v.numbers){
if (v.i->=v.size)
{ v.size+=v.size
v.numbers=realloc(v.numbers,sizeof(int)*v.size);
///i leave to you the error handling
}
v.i++;
printf("%d ",number);
scanf("%d",&number);
}
}
正确使用realloc() malloc()和类似的方法是非常重要的。还有缩放比例的增加。对于数据结构,我将其加倍。对于文本,我按线性顺序