Локальная структура, хранящаяся в глобальном связанном списке (доступ к которой осуществляется в других функциях), работает в VC2010. Это правильно C99 / ANSI? - PullRequest
0 голосов
/ 23 марта 2011

Следующий код работает нормально:


typedef struct node_s {
    void *data;
    struct node_s *next;    
} NODE;

typedef struct test_s
{
    int asdf;
}TEST;
NODE *list_create(void *data)
{
    NODE *node;
    if(!(node=malloc(sizeof(NODE)))) return NULL;
    node->data=data;
    node->next=NULL;
    return node;
}

NODE *list_insert_after(NODE *node, void *data)
{
    NODE *newnode;
    newnode=list_create(data);
    newnode->next = node->next;
    node->next = newnode;
    return newnode;
}

NODE *list, *second, *third;

void localstructtest()
{
    TEST t;
    t.asdf = 10;

    third = list_insert_after(second, (void*)&t);
}

int main()
{
    TEST th;
    TEST* hrm;

    /* Create initial elements of list */
    list=list_create((void*)"First");
    second=list_insert_after(list, (void*)"Second");
    localstructtest();

    hrm = (TEST*)third->data;
    th = *hrm;
    return 1;
}

Структура создается локально в функции, отличной от main, но я смог получить данные из связанного списка вне области действия localstructtest (). Локальные переменные создаются в стеке, верно ли это с этой структурой? Или он действительно создается в куче, а указатель / ссылка остается действительным? Я ожидал, что это ужасно провалится, когда я проверил это. Я признаю, что я программист на C ++ и, возможно, я не совсем понимаю последствия отсутствия передачи по ссылке в C. Если все в порядке, использовать данные структуры, подобные этой, когда эти данные когда-нибудь получаются освобожденный

Спасибо!

Ответы [ 2 ]

2 голосов
/ 23 марта 2011

Неопределенное поведение .Это может сработать, а может и нет, это может превратить ваш компьютер в бородавочника, все в зависимости от фазы луны .

Серьезно: это может работать в небольшой примерной программе, ноэто обязательно взорвется вам в лицо по мере роста программы.

Что касается передачи по ссылке: в C вы сделаете это, передав указатель.Основные правила выделения памяти такие же, как в C ++: локальный struct выделяется в стеке и уничтожается, когда выходит из области видимости.Основное отличие состоит в том, что деструктора никогда не бывает, поэтому вы не можете получить полный RAII.

1 голос
/ 23 марта 2011

Причина, по которой он работает в большинстве систем, заключается в том, что стек не обнуляется при выталкивании кадра.Если вы внесете небольшое, казалось бы, несвязанное изменение в вашу программу, она перестанет работать.

int junk()
{
    char junkdata[100] = {0};
    return 42;
}

int main()
{
    TEST th;
    TEST* hrm;

    /* Create initial elements of list */
    list=list_create((void*)"First");
    second=list_insert_after(list, (void*)"Second");
    localstructtest();
    junk();

    hrm = (TEST*)third->data;
    th = *hrm;
    return 1;
}

Это происходит потому, что junk () перезаписывает структуру в стеке нулями.

...