質問

Basically, I'm trying to convert a bunch of char inputs to ints and assign them to a dynamic int array. The string input and tokenization seem to work fine. The issue (from what I can tell) seems to be with the reallocation of the int array; after the array is reallocated twice, the pointer to the int array returns NULL.

What I tried to do was double the size of the int array every time the number of tokens meets or surpasses (size divided by sizeof(int)). The realloc statement works each time this condition is met.

I thought using a pointer to a pointer was the end-all solution to this. I bet it's some really obvious issue, but I'm at my wit's end here. If you request any further elaboration, I'll try my best. Understand that I've only taken C for a semester and have struggled most of the way.

Also, truth be told, this was part of a class assignment which has since passed. I'd prefer an explanation about what's wrong more than a full-on code, if that's alright.

I have a lot of printf statements, so apologies for any clutter.

EDIT: Replaced all instances of newArray within the input() function with *resize. However, I've never tried assigning values through pointers to pointers, so feel free to correct me with a syntactic example if you know how I messed up. Segmentation fault occurs here:

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++;
}

The source code has been updated to reflect upon this. To make this ridiculously long post a little more subdued, let's state that I did this in main():

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

    input(&newArray);  

    free(newArray);  

Moving on.

/* 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);   

}
役に立ちましたか?

解決

The input function receives both resize and arr. main sends the same pointer to both. This is a bug.

When resize is resized, arr stays the same and may point to an invalid address (when realloc returns a different address).

How to fix: Remove arr function argument and only use resize.

他のヒント

When you call the realloc function,if the new memory block is smaller than previous ,it will maintain the original state pointing to the memory block which previous used.If the new memory block is larger than previous,the system will re allocate memory on the heap and the previous memory is released.

Among other problems:

char *results[MAXTOKEN];

should be

char *results[MAXTOKEN + 1];

because here the maximum value of count will be MAXTOKEN in this loop :

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

and

char str[MAXSTRING];

is pretty scary, because as soon as the user enters more than MAXSTRIN (=11) characters without pressing Enter, you will get a buffer overflow.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top