2017-01-03 8 views
-3

Итак, у меня есть следующий код, и он не работает так, как мне бы хотелось. Поскольку я не специалист по работе со структурами, я не могу найти проблему.проблемы с структурами ссылок и разыменований

typedef struct foo { 
    int a; 
    int b; 
    int c; 

} bar; 


int function(bar *a) { 

    int m[3] = {0}; 

    // 
    //code filling m with values 
    // 

    if (condition == true) { 
     a = (bar*)&m; 
     printf("%d", a->a); 
     status = SUCCESS; 

    } 

    // 
    //other code 
    // 

    return status; 
} 

int main() { 

    int ret=0;   
    bar a; 

    ret = function (&a); 
    if (ret == SUCCESS) { 
     printf(" %d ", a.a); 
    } 
} 

Первый printf (один в функции) выводит правильное значение. Второй - нет. Может ли кто-нибудь помочь мне в этом? Спасибо.

+1

Что заставляет вас думать, что 'int [3]' эквивалентно 'struct foo'? Как вы учитываете * padding *, который компилятор может или не может вставить? Дальше 'a = (bar *) & m;' является * per se * нарушением * строгого правила псевдонимов * (см. [** строгое правило сглаживания **] (http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule)) –

+0

Я видел что-то подобное в другом месте, и я подумал, что могу использовать его здесь, чтобы избавить себя от необходимости вручную заполнить панель a. ЧЕТКО Я ошибался. То, что я хотел сделать, это программа, чтобы читать 3 байта двоичных данных и «вставлять» их на панель a. – user2544187

+0

Есть редко хорошие ярлыки. Вы можете сделать что-то похожее на то, что вы описали, если вы создаете 'bar' как * bitfield * struct, а затем заполняете его' memcpy' или читаете байты непосредственно из потока с помощью 'fread'. Существует много примеров использования битбита на этом сайте. –

ответ

0

Что вы подразумеваете под "Не печатать правильное значение"?

Структура, расположенная на стеке, поэтому ее содержимое неинициализировано. Поэтому то, что вы получаете, полностью случайное, основанное на предыдущем состоянии стека.

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

+0

Я знаю, какое правильное значение зависит от того, как оно заполняется m. Можете ли вы рассказать о том, что вы подразумеваете под «выделенным в стеке»? Какой экземпляр бара или всех экземпляров бара, в том числе? Я подумал, что, указав указатель a на начальную точку m, он заполнил a.a m [0], a.b с m [1] и a.c с m [2]. Возможно, я ошибаюсь. – user2544187

+0

Variable'm' и 'a' - это совершенно разные, несвязанные переменные. Если вы хотите напечатать исходный аргумент 'a', переданный как аргумент, вам нужно избегать строки:' a = (bar *) & m; ' –

+0

Op пытается обрабатывать массив, такой как struct, следовательно, литой. –

2

С назначением a = (bar *) & m вы меняете место, где указывает параметр функции (a) вашей функции, а не содержание переменной в вашей основной функции.

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

Вы можете использовать memcpy для достижения желаемого.

memcpy(a, &m[0], sizeof(bar)); 
+0

Да, я думал, что это может быть проблемой. Есть ли способ сделать это вручную, не используя string.h? Или в любом случае, чтобы заполнить a значениями m? – user2544187

+0

@ user2544187 Почему бы не использовать 'string.h'? – chux

+0

@chux, потому что это встроенное приложение – user2544187