код, который приводит к сбою фреймворка, но при воспроизведении в одном файле он работал - PullRequest
0 голосов
/ 13 июля 2011

У меня есть вопрос относительно этого кода.Я пишу этот код в моем фреймворке, и это вызвало сбой фреймворка.Но когда я переписываю этот код ниже в одном файле, но он работает просто отлично.Мне просто интересно, правильный ли приведенный ниже код для выделения памяти и ее освобождения?(особенно для части msg-> context_var.type = f;) Спасибо

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


typedef struct
{
  int value;
  int price;
  int old;
} type_t;


typedef struct {
  type_t            *type;  
} context_t;


typedef struct {
  context_t context_var; 
} send_request;



void send_Message(send_request *msg)
{   

type_t *f = 0;
f = malloc(sizeof(f));
msg->context_var.type = f;
msg->context_var.type->price = 1;
msg->context_var.type->value = 100;
msg->context_var.type->old =120;


printf("value of %d/n", msg->context_var.type->price);
free(f);
}

int main()
{   

    send_request *msg = 0;
    msg = (send_request *) malloc(sizeof(send_request));

    send_Message(msg);
    free(msg);
    return 0;
}

Ответы [ 3 ]

7 голосов
/ 13 июля 2011

Это неправильно.

f = malloc(sizeof(f)); /* Wrong */
f = malloc(sizeof(*f)); /* Better ? */

sizeof(f) даст вам размер указателя на вашем компьютере; sizeof(*f) даст вам размер объекта, на который указывает .

РЕДАКТИРОВАТЬ По запросу @ Perception

Когда вы выделяете меньше, чем нужно, вы запрашиваете Неопределенное поведение . Может случиться что угодно (даже желаемое поведение), и все это зависит от платформы, окружающей среды (фазы луны и т. Д.).

msg->context_var.type->value = 100; /* Writes beyond what's allocated. */

Таким образом, в зависимости от структуры памяти "фреймворка" это может просто перезаписать часть памяти и "работать", или может произойти сбой. Честно говоря, я предпочитаю, когда он сразу падает.

0 голосов
/ 13 июля 2011

Мало того, что вы выделяете неправильный размер (см. Ответ cnicutar) - Если вы присоединяете f к сообщению, которое передается фреймворком, вы, вероятно, не хотите освобождать его до возврата из функции. Вы должны будете освободить его позже, хотя - вероятно, через какое-то другое средство, предоставляемое платформой?

0 голосов
/ 13 июля 2011

Вы выделяете экземпляр context_t в куче, а затем msg->context_var.type получает значение результирующего указателя f.

Поскольку msg является параметром-указателем для функции send_Message, нельзя сделать надежных предположений о том, что делается с msg и его содержимым после существования вашей функции. Таким образом, когда вы продолжаете освобождать память, указанную f, вы оставляете висячий указатель в msg->context_var.type.

Если доступ к памяти, на которую он указывает, доступен после того, как send_Message существует, есть большая вероятность, что вы испортили что-то жизненно важное (или прочитали что-то сумасшедшее, например указатель на 0xdeadbeef), поскольку оно может теперь содержать что-то совершенно другое.

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