将字符串分配给动态int数组时的重新分配问题

时间:2013-12-17 08:17:56

标签: c arrays realloc atoi

基本上,我正在尝试将一堆char输入转换为int并将它们分配给动态int数组。字符串输入和标记化似乎工作正常。问题(从我所知道的)似乎是重新分配int数组; 在重新分配数组两次之后,指向int数组的指针返回NULL

我试图做的是每次令牌数达到或超过(大小除以sizeof(int))时,int数组的大小加倍。每次满足此条件时,realloc语句都会起作用。

我认为使用指向指针的指针是最终的解决方案。我打赌这是一个非常明显的问题,但我在这里结束了我的智慧。如果您要求进一步详细说明,我会尽力而为。明白我一个学期只学了C并且大部分时间都在努力。

另外,事实上,这是课程作业的一部分,从此过去了。如果可以的话,我更喜欢解释什么是错误的,而不是完整的代码。

我有很多printf语句,所以请为任何混乱道歉。

编辑:用* resize替换input()函数中newArray的所有实例。但是,我从未尝试通过指针指向值来分配值,所以如果你知道我搞砸了,请随意用句法示例来纠正我。此处发生分段错误:

for (k = (numElem - count); k < numElem; k++)
{
    printf("\nk = %i\n", k);
    printf("j = %i\n", j);
    printf("numElem = %i\n", numElem);
    printf("results[j]: %s\n\n\n", results[j]);

    /* Segmentation fault regardless of what is assigned
    to *resize[k]. */
    *resize[k] = atoi(results[j]); // PROBLEM HERE
    j++;
}

源代码已更新以反映此情况。为了使这个可笑的长篇文章更加柔和,让我们说我在main()中做了这个:

    int *newArray = malloc(MAXTOKEN * sizeof(int));

    input(&newArray);  

    free(newArray);  

继续前进。

/* String input takes in char values,
tokenizes them, converts the results
to int, assigns them to newresizeay. */
int input(int **resize)
{
    int i, j, k, count;

    int numElem = 0;
    int currentSize = MAXTOKEN;

    char str[MAXSTRING];
    char *results[MAXTOKEN];

    /* This entire loop takes place at least once,
    provided the first input isn't NULL. */
    do
    {     
        i = 0, j = 0, k = 0;

        /* Char input process. Takes place until the user
        presses ENTER. */
        printf("Input integer values separated by spaces, or "
            "press ENTER to exit.\n");   
        while ( ((str[i] = getchar() ) != '\n') && (i < MAXSTRING) )
            i++;
        printf("\n\n");

        str[i] = '\0';


        /* Tokenization of the chars that were input */
        count = 0;

        if (results[0] = strtok(str, " \t"))
            count++;

        while (results[count] = strtok(NULL, " \t") )
            count++;


        /* numElem = 1 if the first input prompt established
        str[0] as NULL */
        if ( (count < 1) && (numElem < 1) )    
            count = 1;

        numElem += count;

        printf("numElem: %i\ncurrentSize: %i\n", numElem, currentSize);

        /* If the number of elements to assign meet or surpass
        the amount of [memory / sizeof(int)], exponentially
        increase the size of the int resizeay. */
        if ( numElem >= currentSize )
        { 
            *resize = realloc(*resize, (currentSize) * sizeof(int));
            if (*resize == NULL)
                printf("\n\nYep, it threw up.\n\n");
            currentSize *= 2;
        }


        printf("\nSize should be: %i\n", currentSize * 4);
        printf("Actual size: %d\n", _msize(*resize));


        /* The tokenized chars are converted to integers and
        assigned to the int resizeay. */
        for (k = (numElem - count); k < numElem; k++)
        {
            printf("\nk = %i\n", k);
            printf("j = %i\n", j);
            printf("numElem = %i\n", numElem);
            printf("results[j]: %s\n\n\n", results[j]);

            *resize[k] = atoi(results[j]); // PROBLEM HERE
            j++;
        }

        for (i = 0; i < numElem; i++)
            printf("resize[%i]: %i\n", i, *resize[i]);               

        printf("\n\n\n");      

    } while (str[0] != NULL);   

}

3 个答案:

答案 0 :(得分:0)

输入函数同时接收resizearrmain向两者发送相同的指针。这是一个错误。

调整resize时,arr保持不变,并且可能指向无效的地址(当realloc返回不同的地址时)。

如何修复: 删除arr函数参数,仅使用resize

答案 1 :(得分:0)

当你调用realloc函数时,如果新的内存块小于之前的内存块,它将保持指向先前使用的内存块的原始状态。如果新内存块大于之前的内存块,系统将重新分配堆上的内存和先前的内存被释放。

答案 2 :(得分:0)

其他问题包括:

char *results[MAXTOKEN];

应该是

char *results[MAXTOKEN + 1];

因为在这个循环中count的最大值将是MAXTOKEN:

while (results[count] = strtok(NULL, " \t") )
  count++;

char str[MAXSTRING];

非常可怕,因为一旦用户输入超过MAXSTRIN(= 11)个字符而不按Enter键,您将获得缓冲区溢出。