Считает ли выходной параметр нарушающим принцип возврата локальных ссылок? - PullRequest
0 голосов
/ 17 сентября 2011

У меня есть этот код:

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

void getDataFromServer(OUT int** array, OUT int* size)
{
    int tmpArr[] = {0x00, 0x01, 0x02, 0x03,  0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13,  0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    *size = sizeof tmpArr / sizeof(int);
    *array = tmpArr;
}

int main(void)
{
    int size = 0;
    int* dataFromServer;
    getDataFromServer(&dataFromServer, &size);

    int x;
    for (x=0; x < size; x++)
        printf("%d ", dataFromServer[x]);
    printf("\n\n");

    return 0;
}

Цикл for внутри основных печатает данные мусора. Это из-за того, что параметр доступа OUT int** array локально для функции?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 17 сентября 2011

Да, независимо от того, как вы это делаете, вы не можете отправить адрес локальной переменной из функции и ожидать, что он останется действительным, как только функция вернется. Тот же аргумент применим для значений, возвращаемых функцией, или для «параметров out», или, вообще, для установки любой области памяти, указывающей на локальную переменную.

Часто говорят, что переменные удаляются из стека или становятся "мусором"; это помогает понять, что в действительности происходит повторное использование пространства для локальных переменных других функций, для параметров, используемых для вызова других функций и т. д. Вот почему иногда «мусорные» переменные все еще остаются действительными - потому что их пространство еще не было использовано

2 голосов
/ 17 сентября 2011

Да, именно так. Поскольку tmpArr является локальным по отношению к getDataFromServer, оно перестает существовать, когда функция возвращается. Указатели на него теперь являются указателями на мусор.

Вам следует подумать о том, кто отвечает за выделение памяти для хранения данных с сервера и кто отвечает за ее освобождение. В этом случае функция отвечает за его освобождение, что, очевидно, не может работать. Любая сторона может выделить, но абонент должен освободить!

1 голос
/ 17 сентября 2011

Когда выходит getDataFromServer, все локальные переменные выталкиваются из стека. Указатель, который вы используете, теперь указывает на область памяти, которая была более или менее удалена. Либо используйте malloc и скопируйте данные во вновь выделенную память (в куче), либо сделайте tmpArr в переменную static.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...