在处理需要频繁内存分配的程序时,我遇到了无法解释的行为。我已经实施了一项工作,但我很好奇为什么我以前的实现不起作用。情况如下:
指针的内存重新分配有效
这可能不是最佳实践(如果是这样,请让我知道)但我记得如果传入的指针是NULL,则realloc可以分配新的内存。下面是一个示例,我将文件数据读入临时缓冲区,然后为* data和memcopy内容分配适当的大小
我有一个像这样的文件结构
typedef struct _my_file {
int size;
char *data;
}
并且mem重新分配和复制代码如下:
// cycle through decompressed file until end is reached
while ((read_size = gzread(fh, buf, sizeof(buf))) != 0 && read_size != -1) {
// allocate/reallocate memory to fit newly read buffer
if ((tmp_data = realloc(file->data, sizeof(char *)*(file->size+read_size))) == (char *)NULL) {
printf("Memory reallocation error for requested size %d.\n", file->size+read_size);
// if memory was previous allocated but realloc failed this time, free memory!
if (file->size > 0)
free(file->data);
return FH_REALLOC_ERROR;
}
// update pointer to potentially new address (man realloc)
file->data = tmp_data;
// copy data from temporary buffer
memcpy(file->data + file->size, buf, read_size);
// update total read file size
file->size += read_size;
}
指针指向指针的内存重新分配失败
然而,这里是我困惑的地方。使用相同的想法重新分配NULL指针将分配新内存,我解析一个参数字符串,并为每个参数我分配一个指针指针,然后分配一个指针指向指针。也许代码更容易解释:
这是结构:
typedef struct _arguments {
unsigned short int options; // options bitmap
char **regexes; // array of regexes
unsigned int nregexes; // number of regexes
char *logmatch; // log file match pattern
unsigned int limit; // log match limit
char *argv0; // executable name
} arguments;
内存分配代码:
int i = 0;
int len;
char **tmp;
while (strcmp(argv[i+regindex], "-logs") != 0) {
len = strlen(argv[i+regindex]);
if((tmp = realloc(args->regexes, sizeof(char **)*(i+1))) == (char **)NULL) {
printf("Cannot allocate memory for regex patterns array.\n");
return -1;
}
args->regexes = tmp;
tmp = NULL;
if((args->regexes[i] = (char *)malloc(sizeof(char *)*(len+1))) == (char *)NULL) {
printf("Cannot allocate memory for regex pattern.\n");
return -1;
}
strcpy(args->regexes[i], argv[i+regindex]);
i++;
}
当我编译并运行它时,我得到一个运行时错误“realloc:invalid pointer”
我必须遗漏一些显而易见的东西,但是现在没有完成很多试图在线调试和搜索解决方案5小时后,我只运行了两个循环,一个计算参数的数量,mallocs足够的空间,第二个循环为参数分配空间并strcpys它。
非常感谢对此行为的任何解释!我真的很想知道原因。
答案 0 :(得分:1)
第一个片段:
// cycle through decompressed file until end is reached
while (1) {
char **tmp_data;
read_size = gzread(fh, buf, sizeof buf);
if (read_size <= 0) break;
// allocate/reallocate memory to fit newly read buffer
tmp_data = realloc(file->data, (file->size+read_size) * sizeof *tmp_data );
if ( !tmp_data ) {
printf("Memory reallocation error for requested size %d.\n"
, file->size+read_size);
if (file->data) {
free(file->data)
file->data = NULL;
file->size = 0;
}
return FH_REALLOC_ERROR;
}
file->data = tmp_data;
// copy data from temporary buffer
memcpy(file->data + file->size, buf, read_size);
// update total read file size
file->size += read_size;
}
第二片段:
unsigned i; // BTW this variable is already present as args->nregexes;
for(i =0; strcmp(argv[i+regindex], "-logs"); i++) {
char **tmp;
tmp = realloc(args->regexes, (i+1) * sizeof *tmp );
if (!tmp) {
printf("Cannot allocate memory for regex patterns array.\n");
return -1;
}
args->regexes = tmp;
args->regexes[i] = strdup( argv[i+regindex] );
if ( !args->regexes[i] ) {
printf("Cannot allocate memory for regex pattern.\n");
return -1;
}
...
return 0;
}
一些注意事项:
ptr = malloc ( CNT * sizeof *ptr);
比sizeof(type)
变体更强大。i++;
的while()循环更不容易出错。 (它也表明从不检查循环条件)if ( !ptr ) {}
比if (ptr != NULL) {}