简体   繁体   中英

Pointer to Pointer array & Stack Smashing error

I need to allocate an array with a malloc and I have to read some numbers from input. This is my code:

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

void read(int **array, int *array_size)
{
    int *tmp;
    int i;
    scanf("%d", array_size);
    *array=malloc(*array_size*sizeof(int));
    tmp=malloc(*array_size*sizeof(int));
    for(i=0;i<*array_size;i++)
    {
        scanf("%d", &tmp[i]);
        array[i]=&tmp[i];
    }
}

//DO NOT EDIT main()
int main()
{
    int *array;
    int array_size,i;

    read(&array,&array_size);

    printf("Print array:\n");
    for(i=0;i<array_size;i++)
        printf("%d\n", array[i]);

    return 0;
}

It kinda works, but after displaying values it shows a stack smashing detected (I compiled it with GCC).

I thought the problem is that *array=malloc(*array_size*sizeof(int)) , but I can't figure out how to fix it. Is there another way to allocate this array without editing main()? Thank you.

The problem is that you're indexing the wrong array. You should be writing (*array)[i] , not array[i] :

void read(int **array, int *array_size)
{
    int *tmp;
    int i;
    scanf("%d", array_size);
    *array=malloc(*array_size*sizeof(int));
    tmp=malloc(*array_size*sizeof(int));
    for(i=0;i<*array_size;i++)
    {
        scanf("%d", &tmp[i]);
        (*array)[i]=tmp[i];
    }
}

Of course all this is very complicated - you don't need to actually have that tmp , nor do you need to malloc it. Instead you could very well do something like

void read(int **array, int *array_size) {
    int i, *pos;
    scanf("%d", array_size);
    *array = pos = malloc(*array_size * sizeof(int));
    for (i = 0; i < *array_size; i ++, pos ++) {
        scanf("%d", pos);
    }
}

That is we have the pointer pos to point to the current position in the array where we want to scanf the next integer. On each loop we increment the position.

Naturally, you'd want to check the return values of these scanf s and malloc ; and perhaps read should have a different prototype, such as

int *read(int *array_size);

so it could return the pointer to the array directly, or NULL on error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM