realloc 似乎不适用于指向指针的指针

realloc not appearing to work for pointers to pointers

当我尝试使用realloc作为指针的外部指针时,内存地址一直在变化,即使我将它设置回原来的指针。

这是下面的代码。 reallocread_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 变量。