【问题标题】:c - realloc() on tokenized array: signal SIGABRT errorc - 标记化数组上的 realloc():信号 SIGABRT 错误
【发布时间】:2015-07-08 09:34:45
【问题描述】:

在第 56 行,我正在尝试调整数组的大小:

tokenArray = (char**) realloc(tokenArray, tokSize * (sizeof(char)));

我收到一个错误:

(11972,0x7fff7ca4f300) malloc: * 对象 0x100105598 错误:已释放对象的校验和不正确 - 对象可能在被释放后被修改。 * 在 malloc_error_break 中设置断点进行调试

这是一个类的编程作业,我被特别指示动态分配我的数组,然后根据需要进行扩展。我已经广泛搜索了另一个线程,这对我来说不太先进,无法理解,还没有运气......所以希望我能得到一些帮助。谢谢!这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_ROW_SIZE 81

void strInput(char str[], int numElem);


int main(int argc, const char * argv[])
{
    printf("Enter a string of any number of integers separated by spaces or tabs.\n");
    printf("Maximum string length is 80 characters.\n");
    printf("Enter an empty string to conclude input.\n");


    int arrSize = 10, tokSize = 10, i = 0, j = 0;

    char** inputArray = malloc(arrSize * (sizeof(char)));
    char** tokenArray = malloc(tokSize * (sizeof(char)));


    do {
        inputArray[i] = malloc(MAX_ROW_SIZE * sizeof(int));

        strInput(inputArray[i], arrSize);

        if ((inputArray[i][0] != '\0') && (i == (arrSize - 1)))
        {
            arrSize = arrSize * 2;
            inputArray = (char**) realloc(inputArray, arrSize * (sizeof(char)));
        }

        while (inputArray[i][j] != '\0')
        {
            printf("%c", inputArray[i][j]);
            j++;
        }
        j = 0;

        i++;
    } while (inputArray[i-1][0] != '\0');

    i = 0;

    while (inputArray[i][0] != '\0')
    {

        if ((tokenArray[j] = strtok(inputArray[i], " \t")))
            j++;
        while ((tokenArray[j] = strtok(NULL, " \t")))
        {
            if (j == (tokSize - 1))
            {
                tokSize = 2 * tokSize;

 //This is the line where I get the error
                tokenArray = (char**) realloc(tokenArray, tokSize * (sizeof(char)));
            }
            j++;
        }
        i++;
    }

    printf("printing the tokenized arrays: ");
    for (i = 0; i < j; i++)
        printf("%s ", tokenArray[i]);

    free(inputArray);
    free(tokenArray);

    return 0;
}

void strInput(char str[], int numElem)
{


    int j, k = 0;

    j = k;

    while ((str[k] = getchar()) != '\n')
    {
        k++;
    }

    if (str[k] == '\n')
        str[k] = '\0';
}

【问题讨论】:

  • 让我担心的一件事是tokenArray 是一个指向char 的指针,但您只是使用sizeof(char) 而不是sizeof(char *) 进行分配。因此,您的初始分配是一个由十个 字符 组成的数组,而不是十个指向字符的指针。
  • 正如@JoachimPileborg 所提到的,这个:char** inputArray = malloc(arrSize * (sizeof(char))); 应该是char** inputArray = malloc(arrSize * sizeof *inputArray);。这可以保护您免受自己的伤害,并使分配具有适当的大小。这种模式总是有效的。
  • 哇...就是这样!非常感谢你们俩!我真的尝试在这里发帖作为绝对的最后手段:D
  • 警告:你should not cast malloc 的回归。第二个警告:当在malloc(等)you should always write it 中调用sizeof 作为ptr = malloc(sizeof(*ptr) * ...); 而不是ptr = malloc(sizeof(ptrtype*) * ...);
  • because arrays are naturally pointers to addresses 这不是真的。你用char*-指针创建了一个数组,是的,但也可以创建一个charintstruct 和任何其他类型的数组。

标签: c pointers dynamic-arrays realloc sigabrt


【解决方案1】:

1. Do not cast the result of malloc and friends.

它充其量是无用的,最坏的情况是危险的。

2。注意你的大小malloc'ing。

char** inputArray = malloc(arrSize * (sizeof(char)));

这毫无意义,而且很可能是偶然的。根据经验,malloc'ing 所针对的类型和指向结果存储的指针应该只存在一个间接差异。即:

char** inputArray = malloc(arrSize * sizeof(char*));
//  ^^ Double-pointer     vs     Single pointer ^

更好的经验法则,让编译器弄清楚。 sizeof 可以从表达式中推断出它应该测量的类型。

char **inputArray = malloc(arrSize * sizeof(*inputArray));

这是因为sizeof 的操作数是一个未评估的上下文。指针实际上不会被取消引用,只会推断其类型。
旁注:sizeof 的括号不需要围绕表达式,但为了清楚起见,我把它们留下了。一旦你觉得舒服就删除它们。

3。检查分配是否成功。

malloc 和朋友会在遇到问题时返回NULL。你应该检查一下。

4。修复你的realloc

inputArray = realloc(inputArray, /*...*/);

这是错误的。如上所述,如果realloc 失败,它将返回NULL并且不执行任何其他操作。这意味着inputArray 仍指向其先前的存储。也就是说,直到你用刚刚返回的NULL realloc 胜过这个指针,并泄漏所说的存储。哎呀。

始终存储、检查并然后分配realloc的结果。

char **inputArray_ = realloc(inputArray, /*...*/);
if(!inputArray_) {
    /* Allocation failure, handle it and break out */
}
inputArray = inputArray_;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多