我一直在寻找类似性质的其他答案,但仍然遇到问题。
我是C的初学者,需要一些建议。
代码的相关部分:
int readNumbers(int **array, char* fname, int hexFlag) {
int numberRead = 0;
FILE* fp;
int counter = 0;
char arr[100];
char* ptr;
array = malloc(0 * sizeof(*array)); //Problematic area. Should I initially give it space?
fp = fopen(fname, "r");
if (fp == NULL) {
printf("Error opening file\n");
return -1;
}
while (fgets(arr, sizeof(arr), fp)) {
ptr = strtok(arr, " \n");
while(ptr) {
if (hexFlag == 0) {
array = realloc(array, (counter + 1) * sizeof(int*));
array[counter++] = strtol(ptr , NULL , 10); //Seg Faulting
} else {
array = realloc(array, (counter + 1) * sizeof(int*));
array[counter++] = strtol(ptr, NULL, 16);
}
++numberRead;
ptr = strtok(NULL , " \n");
}
}
我调试了这个,似乎数组永远不会分配给它的内存。此外,程序在我尝试通过array[counter++]
;
我还发现每次增量后重新分配是不好的做法,但我不知道还能做什么。
答案 0 :(得分:1)
经验法则是分配一个小的初始分配,并在需要更多空间时将分配的大小加倍。您必须跟踪两种尺寸 - 分配的尺寸和使用的尺寸。您可以使用realloc()
完成所有操作,但首先使用malloc()
然后realloc()
可能更为常规。
size_t n_alloc = 1;
size_t n_used = 0;
int *data = malloc(n_alloc * sizeof(*arr));
if (arr == 0)
…report out of memory and return…
int base = (hexFlag == 0) ? 10 : 16;
while (fgets(arr, sizeof(arr), fp))
{
ptr = strtok(arr, " \n");
while (ptr)
{
if (n_used == n_alloc)
{
size_t new_size = n_alloc * 2;
int *new_data = realloc(data, new_size);
if (new_data == 0)
{
free(data);
…report error and return…
}
data = new_data
n_alloc = new_size;
}
data[n_used++] = strtol(ptr, NULL, base);
ptr = strtok(NULL, " \n");
}
}
/* Optionally resize array */
*array = realloc(data, n_used * sizeof(*data));
/* Or, instead of realloc(), just write: *array = data; */
return n_used;
或者,初始化可以是:
size_t n_alloc = 0;
size_t n_used = 0;
int *data = 0;
这也可行;它甚至减少了需要错误报告的地方数量。
请注意,在realloc()
失败的情况下,代码会小心避免内存泄漏。写这是错误的:
ptr = realloc(ptr, size);
如果realloc()
失败,ptr
被指定为NULL,这意味着您无法释放在调用realloc()
之前分配的内存,这是一个典型的内存泄漏。
另请注意,此代码正确处理array
(int **
}和data
(int *
)。问题中的原始代码是将array
视为int *
,而不是int **
。
答案 1 :(得分:1)
每次循环都是realloc
的不良做法。根据需要在更大的区块内成长会更好。
此外,您正在错误地分配数组。 array
是一个指向整数数组的指针,你需要间接通过它来设置调用者的指针。
*array = malloc(size * sizeof(**array));
所以你的功能应该是这样的:
int readNumbers(int **array, char* fname, int hexFlag) {
int numberRead = 0;
FILE* fp;
int counter = 0;
char arr[100];
char* ptr;
size_t curSize = 16;
int radix = hexFlag ? 16 : 10;
*array = malloc(curSize * sizeof(**array));
fp = fopen(fname, "r");
if (fp == NULL) {
printf("Error opening file\n");
return -1;
}
while (fgets(arr, sizeof(arr), fp)) {
ptr = strtok(arr, " \n");
while(ptr) {
if (counter >= curSize) {
curSize += 16;
*array = realloc(*array, curSize * sizeof(**array));
}
(*array)[counter++] = strtol(ptr , NULL , radix);
++numberRead;
ptr = strtok(NULL , " \n");
}
}
}