Вопрос по структурам С

valkiria77

Добрый день, столкнулся с проблемой, при написании программы на С. Сразу скажу, что С совсем не родной и не fluent :) .
Ошибку удалось воспроизвести в таком редуцированном варианте.
Платформа: cygwin, компилятор gcc
 
/* 
* File: main.c
* Author: Shellenberg
*
* Created on 7 Октябрь 2012 г., 4:20
*/

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

/*
*
*/

typedef struct _Inputs {
int COUNT;
float *inputs;
} Inputs;

typedef struct _Outputs {
int COUNT;
float *outputs;
} Outputs;

typedef struct _Data {
Inputs inputs;
Outputs outputs;
} Data;

Data data;

Data getTestSinData {
Inputs input;
input.inputs = (float[]){1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
input.COUNT = 9;
Outputs output;
output.COUNT = 9;
output.outputs = (float[]){0.84, 0.90, 0.14, -0.75, -0.95,
-0.27, 0.65, 0.98, 0.41};
data.inputs = input;
data.outputs = output;
for (int k = 0; k < input.COUNT; k++) {
printf("INIT: Inputs is %F pointer is %p\n", input.inputs[k], input.inputs + k);

}
return data;
}

void testInputs(Inputs in) {
for (int k = 0; k < in.COUNT; k++) {
printf("FF: Inputs is %F pointer is %p\n", in.inputs[k], in.inputs + k);
}
}

int main(int argc, char** argv) {
testInputs(getTestSinData.inputs);
return (EXIT_SUCCESS);
}


Вывод:
 
INIT: Inputs is 1.000000 pointer is 0x28abd0
INIT: Inputs is 2.000000 pointer is 0x28abd4
INIT: Inputs is 3.000000 pointer is 0x28abd8
INIT: Inputs is 4.000000 pointer is 0x28abdc
INIT: Inputs is 5.000000 pointer is 0x28abe0
INIT: Inputs is 6.000000 pointer is 0x28abe4
INIT: Inputs is 7.000000 pointer is 0x28abe8
INIT: Inputs is 8.000000 pointer is 0x28abec
INIT: Inputs is 9.000000 pointer is 0x28abf0
FF: Inputs is 1.000000 pointer is 0x28abd0
FF: Inputs is 177688942755763453952.000000 pointer is 0x28abd4
FF: Inputs is 0.000000 pointer is 0x28abd8
FF: Inputs is 171112543807709642752.000000 pointer is 0x28abdc
FF: Inputs is 0.000000 pointer is 0x28abe0
FF: Inputs is 175780560005851250688.000000 pointer is 0x28abe4
FF: Inputs is 0.000000 pointer is 0x28abe8
FF: Inputs is 0.000000 pointer is 0x28abec
FF: Inputs is 0.000000 pointer is 0x28abf0
  

Т.е. при чтении значений массива из функции где они устанавливаются, все нормально, но при передаче управления в другую ф-цию и чтения тех же ячеек памяти в них лежит какая-то лажа.
Кто нить может помочь определить ошибку?

ppplva

Твои float[] живут в фрейме getTestSinData и умирают при выходе.

ppplva

Не удержусь и пропиарю мегатул:
 
# clang -std=c99 1.c -o 1 -faddress-sanitizer -mllvm -asan-use-after-return=1
# ./1
ERROR: AddressSanitizer stack-use-after-return on address 0x7f473b643260 at pc 0x40726a bp 0x7fffcc5260d0 sp 0x7fffcc5260c8
READ of size 4 at 0x7f473b643260 thread T0
0x40726a in testInputs /tmp/test/1.c:51
0x4075e5 in main /tmp/test/1.c:56
0x7f473be61eff in ? ?:0
Address 0x7f473b643260 is located at offset 96 in frame <getTestSinData> of T0's stack:
This frame has 5 object(s):
[32, 48) 'input'
[96, 132) '.compoundliteral'
[192, 208) 'output'
[256, 292) '.compoundliteral9'
[352, 356) 'k'

valkiria77

Угу, понятно, благодарю

valkiria77

Под gcc мегатул, к сожалению, не работает , но благодарю за наводку, надо посмотреть в сторону подобных анализаторов ошибок использования памяти

Lord456

под gcc для таких вещей работает valgrind

salamander

Он хотел, видимо, сказать "под винду". Но под винду валгринд тоже не работает. Бывает Pin (www.pintool.org который делает то же самое, что и валгринд.

ppplva

Вот все что валгринд может сказать в этом случае:
 ==3672== Conditional jump or move depends on uninitialised value(s)
==3672== at 0x4E7BA22: __printf_fp (printf_fp.c:404)
==3672== by 0x4E781E4: vfprintf (vfprintf.c:1628)
==3672== by 0x4E81275: printf (printf.c:35)
==3672== by 0x4006E5: testInputs (1.c:51)
==3672== by 0x400724: main (1.c:56)
==3688== Uninitialised value was created by a stack allocation
==3688== at 0x400687: testInputs (1.c:49)

Без поддержки со стороны компилятора очень сложно понять что происходит на стеке.

xronik111

Если успеют, поддержку асана хотят сделать в 4.8. Тогда выйдет следующей весной. Если не успеют — еще следующей весной :)
Оставить комментарий
Имя или ник:
Комментарий: