首页 > 解决方案 > realloc():strtok 操作中的下一个大小无效

问题描述

在我程序的这一部分中,我试图模仿 ftp 服务器中的 CDUP 操作。首先,我得到客户端所在的当前目录 (ptr2buf3),然后我尝试剥离最后一个由分隔的字符串/,以确定如果我们上一个目录的路径是什么。但是,只有当我进入另一个目录、回来并再次尝试 CDUP(即从根目录向上)时,我才会收到 realloc 错误

                char *ptr2;
                char buf3[255];
                // Get current directory of application, store in buf3
                if ((ptr2 = getcwd(buf3, sizeof(buf3))) != NULL) {
                    printf("Current working dir CDUP: %s\n", buf3);
                } else {
                    perror("getcwd() error");
                }

                // Strip current directory off buf3 
                char *cdupSplit = strtok(buf3, "/");
                char *cdupAccumulator = NULL;
                char *newStr = calloc(1, strlen(cdupSplit));
                while (cdupSplit != NULL) {
                    if (cdupAccumulator != NULL) {
                        newStr = realloc(newStr, strlen("/"));
                        newStr = realloc(newStr, strlen(cdupAccumulator));
                        strcat(newStr, "/");
                        strcat(newStr, cdupAccumulator);
                    }
                    cdupAccumulator = cdupSplit;
                    cdupSplit = strtok(NULL, "/");
                }
                ...
                free(newStr);

错误说realloc(): invalid next size: 0x0000000001ac0a20 ***

我不确定我哪里出错了,因为我正在释放newStr变量并且它没有被传递到命令的下一个问题中。

标签: crealloccalloc

解决方案


这部分没有多大意义:

             if (cdupAccumulator != NULL) {
                    newStr = realloc(newStr, strlen("/"));
                    newStr = realloc(newStr, strlen(cdupAccumulator));
                    strcat(newStr, "/");
                    strcat(newStr, cdupAccumulator);
                }

您不断向字符串添加新内容,但一次又一次地调整它的大小以仅保留最后一部分。

You seem to assume that realloc increases the size be the given parameter. This is not the case. (Even then there is no space for terminating \0) You need to keep track of the current size and add to this size accordingly.

For example like this:

if (cdupAccumulator != NULL) {
                newStr = realloc(newStr, strlen(newStr) + strlen(cdupAccumulator) + 2);
                strcat(newStr, "/");
                strcat(newStr, cdupAccumulator);
            }

推荐阅读