LINUX.ORG.RU

Помогите! Я непонимаю почему! это баг С?


0

0

#include <stdio.h>
#define MAX 64
char ** create_pair( char * s1, char * s2 )
{
char ** str;

str = (char **) malloc( 2 );
str[0] = (char *) malloc( MAX );
strcpy( str[0], s1 );
str[1] = (char *) malloc( MAX );
strcpy( str[1], s2 );
return str;
}
int main( int argc, char ** argv )
{
int i;
char *** par;
par = (char ***) malloc( 13 );

par[0] = create_pair( "name0", "value0" );
par[1] = create_pair( "name1", "value1" );
par[2] = create_pair( "name2", "value2" );
par[3] = create_pair( "name3", "value3" );
par[4] = create_pair( "name4", "value4" );
par[5] = create_pair( "name5", "value5" );
par[6] = create_pair( "name6", "value6" );
par[7] = create_pair( "name7", "value7" );
par[8] = create_pair( "name8", "value8" );
par[9] = create_pair( "name9", "value9" );
par[10] = create_pair( "name10", "value10" );
par[11] = create_pair( "name11", "value11" );
par[12] = create_pair( "name12", "value12" );

printf( "Hello, world!\n" );
for( i=0; i<13; i++ ) {
printf( "%d: \"%s\"=\"%s\"\n", i, par[i][0], par[i][1] );
}
return 0;
}

Полезная или нет, но выводит при запуске такое:

Hello, world!
0: "h╟"=P"
1: "name1"="value1"
2: "name2"="value2"
3: "name3"="value3"
4: "name4"="value4"
5: "name5"="value5"
6: "name6"="value6"
7: "name7"="value7"
8: "name8"="value8"
9: "name9"="value9"
10: "name10"="value10"
11: "name11"="value11"
12: "name12"="value12"

в 0: - чепуха, а должно быть: 0: "name0"="value0"

Помогите!
Если я что-то недогоняю, ткните носом!!!
Спасибо

anonymous

< str = (char **) malloc( 2 ); > str = (char **) malloc(2 * sizeof(char *));

< par = (char ***) malloc( 13 ); > par = (char ***) malloc(13 * sizeof(char *));

because a pointer needs 4 bytes on ia32

anonymous
()

> str = (char **) malloc( 2 );

malloc(2 * sizeof(char**))

int19h ★★★★
()
Ответ на: комментарий от ananas

> в таких случаях лучше calloc использовать

Зачем? Чтоб лишний раз память нулями забить (которые все равно тут же
затираются)?

int19h ★★★★
()
Ответ на: комментарий от int19h

> Зачем? Чтоб лишний раз память нулями забить (которые все равно тут же затираются)?

более понятно, имхо. к тому-же нули тут же затираются только в приведенном примере.

ananas ★★★★★
()
Ответ на: комментарий от ananas

> более понятно, имхо.

Что именно более понятно? Тому, кто не знает арифметику?

> к тому-же нули тут же затираются только в приведенном примере.

Вот именно, или ты думаешь, они в выделенном блоке сами появляются
волшебным образом, без затраты времени? =)

int19h ★★★★
()
Ответ на: комментарий от Keiko

> только не говорите, что это будет тормозить ;)

А зачем тогда вообще на C писать?

watashiwa_daredeska ★★★★
()

Мдя... я сам даже немного загрузился сначала))))

Оставляя в стороне уровень кода (типа что неплохо бы проверять длину аргументов в create_pare и результат malloc на NULL, а лучше делать malloc от strlen(s)), смутно вспоминаю что обычно пишут malloc(size*sizeof(type)) - тогда все работает.

почему такие парадоксальные рез-ты были? Разрушение 0-й пары (или не 0-й - в общем той которая первой созхдавалась) происходило где то в середине блока присваиний par[i] = create_pare(...). Потому что памяти под par выделено было в 4 раза меньше чем нужно, и соотвественно в какой то момент на пути этого присаивания оказывался кусок памяти выделенный под первую пару. Если в таком духе сделать массив par подлинее, то разрушены будут 2-я, 3-я и т.д. пары.

par=...776

1-я str = ...800

2-я str = ...960

par реально занимает 13*4 = 52байта, как раз 776+52 = 828 - т.е. как раз первой паре кирдык, а до второй добраться неуспели.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Совсем торможу под утро, уже все сказали выше)))))))

AIv ★★★★★
()
Ответ на: комментарий от Keiko

> только не говорите, что это будет тормозить ;)

Ну дык =)

$ time ./alloc malloc

real 0m0.102s
user 0m0.081s
sys 0m0.015s

$ time ./alloc calloc

real 0m0.109s
user 0m0.091s
sys 0m0.013s

вотъ =)

int19h ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.