【问题标题】:Reverse string realloc(): invalid next size [duplicate]反向字符串 realloc():下一个大小无效 [重复]
【发布时间】:2013-10-18 15:19:09
【问题描述】:

我创建了这个小程序来反转一个句子。 所以给定:a b c d

它会给出:d c b a

这很好用,直到我添加一个额外的字母。如果我尝试“a b c d e”,它将在最后一个失败并出现错误

realloc():下一个大小无效:0x0000000000602010 *

这里是代码

#define MAX_TEXT 100

#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //realloc


int main(int argc, char **argv) {
    char text[MAX_TEXT] = { 0 };    
    char *parts = NULL;

    printf("Insert string: ");
    fgets(text,MAX_TEXT,stdin);
    sscanf(text,"%[^\n]",text); //remove the \n


    char **reverse = NULL;
    char **extra = NULL;
    int size = 0;
    int i = 0;

    parts = strtok (text," ");
    while (parts != NULL) {

        size += ((strlen(parts)+4) * sizeof(char));
        extra = realloc(reverse,size);

        if (extra) {
            reverse = extra; 
            reverse[i++] = parts;
        }     
        else {
            printf("Error allocating memory\n");
            exit(1);
        }

        parts = strtok (NULL, " ");
    }

    while (--i >= 0) {
        printf("%s ",reverse[i]);                
    }

    printf("\n");
}

我仍然是使用指针的新手,更不用说指向指针的指针了,所以任何帮助都会很棒。 谢谢!

Ps:我尝试使用 valgrind,它只是指出 realloc 有问题,但我不明白到底是什么。

更新代码:

#define MAX_TEXT 500

#include <stdio.h>
#include <string.h> //strchr
#include <stdlib.h> //realloc


int main(int argc, char **argv) {
    char text[MAX_TEXT] = { 0 };        

    printf("Insert string: ");
    fgets(text,MAX_TEXT,stdin);
    //sscanf(text,"%[^\n]",text); //remove the \n <-- Undefined behaviour :D "if copying takes place between objects that overlap, the behavior is undefined."
    char *theEnter = strchr(text,'\n');
    if (theEnter) {
        *theEnter = 0;//remove \n
    }        

    char **reverse = NULL;
    char **extra = NULL;
    char *parts = NULL;
    int size = 0;
    int i = 0;
    size_t increse_by = sizeof(char *);

    parts = strtok (text," ");
    while (parts != NULL) {

        size += increse_by; //pointer to pointer so increase by the size of new pointer
        extra = realloc(reverse,size);

        if (extra) {
            reverse = extra; 
            reverse[i++] = parts;
        }     
        else {
            printf("Error allocating memory\n");
            exit(1);
        }

        parts = strtok (NULL, " ");
    }

    while (--i >= 0) {
        printf("%s ",reverse[i]);                
    }

    printf("\n");
}

根据 Charlie Burns 的指示,我现在正在为 char * 分配,我还删除了 sscanf 函数并使用 strchr 删除了 \n,因为正如 chux 所指出的,我所做的是未定义的行为。

感谢您的帮助:)

【问题讨论】:

  • 工作正常。检查此链接ideone.com/ly8ws2
  • 这意味着什么。 OP 的行为未定义
  • OP 正在为 char* 和字符串本身分配空间,而他确实应该只为 char* 数组分配空间。

标签: c memory-management realloc


【解决方案1】:

您的 realloc 没有分配足够的空间。 sizeof(char *) 在你的机器上可能是 8。 下面的 realloc 将为 strlen == 1 的一部分分配 (1 + 4) * 1 = 5。这对于字符串指针来说是不够的。

尝试改变

    size += ((strlen(parts)+4) * sizeof(char));

    size += sizeof(char *);

原因是 extrareverse 是 char **。所以它们是一个指向字符串的指针数组。通过strtok() 的每个循环,该数组都会变大。 strtok() 返回一个以空字符结尾的字符串。所以你不需要为此分配内存。

在这种情况下你不需要这样做,但你也可以这样做:

reverse[i++] = strdup(parts);

如果您想让reverse 中的字符串指向text 中的字符串副本,而不是在text 本身内部。

【讨论】:

  • sscanf(text,"%[^\n]",text)有什么想法吗?无论是小说还是UB。我_认为它是 UB,因为 restrict in int sscanf(const char * restrict s, const char * restrict format, ...)
  • @chux,我真的很老派,没有跟上最近的变化,包括限制。所以我不能明智地对此发表评论。如果限制意味着指针不应该重叠,那么我认为你有一个观点。
  • @chux,你的问题很好,你应该在 StackOverflow 上提问,看看大家怎么说。
  • @CharlieBurns 对!它是一个指向指针的指针,所以我应该增加一个 char 指针而不是 char。谢谢:)
  • @chux 我已经删除了 sscanf 而是使用 strchr 来查找 \n 并将其替换为 0 谢谢 :)
猜你喜欢
  • 2011-02-25
  • 2012-10-31
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 2020-12-27
相关资源
最近更新 更多