realloc 似乎不适用于指向指针的指针
realloc not appearing to work for pointers to pointers
当我尝试使用realloc
作为指针的外部指针时,内存地址一直在变化,即使我将它设置回原来的指针。
这是下面的代码。 realloc
在 read_list
函数中。我尝试通过仅使用指向指针的准系统指针并重新分配来重现该问题,并且成功了,因此错误可能在其他地方,但我无法查明它,因此包含了所有代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INIT_MEM 32
int read_list(char **, char *);
int main(int argc, char *argv[])
{
char **dict;
if (argc != 2) {
fprintf(stderr, "[ERROR]: Usage is \"%s <dict> <list>\"\n", argv[0]);
return(1);
}
dict = malloc(INIT_MEM);
if (read_list(dict, argv[1])) return(1);
printf("&dict[0]: %d\n", &dict[0]);
return(0);
}
int read_list(char **dest, char *file_name)
{
FILE *stream; /* list of words file */
char ch; /* current char read */
int i, j, k, start, read_mode; /* start: file position beginning of each line; see initializations for rest */
int total_memory; /* COUNTS MEMORY */
int i_mem = INIT_MEM; /* initial memory */
stream = fopen(file_name, "r");
if (stream == NULL) {
fprintf(stderr, "[ERROR]: Invalid input file!");
return(1);
}
i = 0, j = 0, k = 0, total_memory = 0; /* i: size counter; j = word counter; k = ch counter */
read_mode = 1; /* 1: true; 0: false */
while ((ch = fgetc(stream)) != EOF) { /* read in each characters */
if (ch == '\n') { /* after reaching end of line */
if (read_mode) { /* if in read-mode */
while (total_memory >= i_mem) { /* allocate more memory for dest if hit upper limit */
i_mem *= 2; /* double the memory size */
printf("IN_TM_BEFORE@%d= &dest[0]: %d\n", i_mem, &dest[0]);
dest = realloc(dest, i_mem); /* allocate increased memory into dest */
printf("IN_TM_AFTER@%d= &dest[0]: %d\n", i_mem, &dest[0]);
/* printf("i_mem:%d\n", i_mem); =================== */
if (dest == NULL) {
fprintf(stderr, "[ERROR]: Memory reallocation failed!\n");
return(1);
}
}
dest[j] = malloc(i); /* allocate string with i, the size of word*/
total_memory += i + 1; /* increase allocated memory mount by size + 1 to account for pointer*/
read_mode = 0; /* turn to transfer mode */
fseek(stream, start - 1, SEEK_SET); /* move back to start of word to transfer */
} else {
i = 0, k = 0; /* reset */
read_mode = 1; /* go to read mode */
j++; /* allow recording for next word */
}
}
else {
if (read_mode) { /* determine length of string */
if (i == 0) start = ftell(stream); /* record start of word for transfer mode */
i++; /* count characters in word */
} else { /* record string */
dest[j][k++] = ch;
}
}
}
printf("FINAL: &dest[0]: %d\n", &dest[0]);
return(0);
}
================================= dict.txt ========= ======================
flyer
go
crabulus
prose
humperdoodle
moo
dragon
enderman
yellow
abonobo
我已经尝试将外部指针(指向指针的指针)更改为 5000 的大小并删除 realloc
并且内存地址没问题,但是当我包含 realloc
时,问题出现了。
当我realloc
时,我得到这个结果:
IN_TM_BEFORE@64= &dest[0]: 35962896
IN_TM_AFTER@64= &dest[0]: 35963690
IN_TM_BEFORE@128= &dest[0]: 35963690
IN_TM_AFTER@128= &dest[0]: 35963888
FINAL: &dest[0]: 35963888
&dict[0]: 35962896
这似乎暗示在我 realloc
之后,指针没有被设置回 dest
,即使我 dest = realloc(dest, i_mem);
关键是你正在设置一个局部变量,如果你想反映对作为参数传递的变量的更改,你需要一个额外的间接级别,例如:
int read_list(char ***dest, char *file_name)
{
...
*dest = realloc(...);
}
int main(int argc, char *argv[])
{
..
read_list(&dict, ...);
}
这将使更改对外部可见,否则只会更改本地 dest
变量。
当我尝试使用realloc
作为指针的外部指针时,内存地址一直在变化,即使我将它设置回原来的指针。
这是下面的代码。 realloc
在 read_list
函数中。我尝试通过仅使用指向指针的准系统指针并重新分配来重现该问题,并且成功了,因此错误可能在其他地方,但我无法查明它,因此包含了所有代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INIT_MEM 32
int read_list(char **, char *);
int main(int argc, char *argv[])
{
char **dict;
if (argc != 2) {
fprintf(stderr, "[ERROR]: Usage is \"%s <dict> <list>\"\n", argv[0]);
return(1);
}
dict = malloc(INIT_MEM);
if (read_list(dict, argv[1])) return(1);
printf("&dict[0]: %d\n", &dict[0]);
return(0);
}
int read_list(char **dest, char *file_name)
{
FILE *stream; /* list of words file */
char ch; /* current char read */
int i, j, k, start, read_mode; /* start: file position beginning of each line; see initializations for rest */
int total_memory; /* COUNTS MEMORY */
int i_mem = INIT_MEM; /* initial memory */
stream = fopen(file_name, "r");
if (stream == NULL) {
fprintf(stderr, "[ERROR]: Invalid input file!");
return(1);
}
i = 0, j = 0, k = 0, total_memory = 0; /* i: size counter; j = word counter; k = ch counter */
read_mode = 1; /* 1: true; 0: false */
while ((ch = fgetc(stream)) != EOF) { /* read in each characters */
if (ch == '\n') { /* after reaching end of line */
if (read_mode) { /* if in read-mode */
while (total_memory >= i_mem) { /* allocate more memory for dest if hit upper limit */
i_mem *= 2; /* double the memory size */
printf("IN_TM_BEFORE@%d= &dest[0]: %d\n", i_mem, &dest[0]);
dest = realloc(dest, i_mem); /* allocate increased memory into dest */
printf("IN_TM_AFTER@%d= &dest[0]: %d\n", i_mem, &dest[0]);
/* printf("i_mem:%d\n", i_mem); =================== */
if (dest == NULL) {
fprintf(stderr, "[ERROR]: Memory reallocation failed!\n");
return(1);
}
}
dest[j] = malloc(i); /* allocate string with i, the size of word*/
total_memory += i + 1; /* increase allocated memory mount by size + 1 to account for pointer*/
read_mode = 0; /* turn to transfer mode */
fseek(stream, start - 1, SEEK_SET); /* move back to start of word to transfer */
} else {
i = 0, k = 0; /* reset */
read_mode = 1; /* go to read mode */
j++; /* allow recording for next word */
}
}
else {
if (read_mode) { /* determine length of string */
if (i == 0) start = ftell(stream); /* record start of word for transfer mode */
i++; /* count characters in word */
} else { /* record string */
dest[j][k++] = ch;
}
}
}
printf("FINAL: &dest[0]: %d\n", &dest[0]);
return(0);
}
================================= dict.txt ========= ======================
flyer
go
crabulus
prose
humperdoodle
moo
dragon
enderman
yellow
abonobo
我已经尝试将外部指针(指向指针的指针)更改为 5000 的大小并删除 realloc
并且内存地址没问题,但是当我包含 realloc
时,问题出现了。
当我realloc
时,我得到这个结果:
IN_TM_BEFORE@64= &dest[0]: 35962896
IN_TM_AFTER@64= &dest[0]: 35963690
IN_TM_BEFORE@128= &dest[0]: 35963690
IN_TM_AFTER@128= &dest[0]: 35963888
FINAL: &dest[0]: 35963888
&dict[0]: 35962896
这似乎暗示在我 realloc
之后,指针没有被设置回 dest
,即使我 dest = realloc(dest, i_mem);
关键是你正在设置一个局部变量,如果你想反映对作为参数传递的变量的更改,你需要一个额外的间接级别,例如:
int read_list(char ***dest, char *file_name)
{
...
*dest = realloc(...);
}
int main(int argc, char *argv[])
{
..
read_list(&dict, ...);
}
这将使更改对外部可见,否则只会更改本地 dest
变量。