LINUX.ORG.RU

SEGFAULT в массиве строк.


0

0

Имеем код, который должен создавать  массив из 5ти нуль-строк, заполнить их, вывести, и освободить память. Но:
        1) В arr[0] частичный мусор появляется
        2) Происходит ошибка сегментации при освобождении памяти.
Подскажите плз. в каком месте проблемы, и как их исправить? спасибо.


      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4
      5
      6 int main(void)
      7 {
      8         char** arr;
      9         int i;
     10
     11         arr = (char **)malloc(5);
     12         for(i = 0; i < 5; i++){
     13                 arr[i] = (char *)calloc(100, sizeof(char));
     14                 sprintf(arr[i], "just it is a test %d\0", i);
     15         }
     16
     17         for(i = 0; i < 5; i++)
     18                 printf("arr[%d] = '%s'\n", i, arr[i]);
     19
     20
     21         for(i = 0; i < 5; i++)
     22                 free(arr[i]);
     23
     24         free(arr);
     25
     26         return 0;
     27 }
anonymous

Ответ на: комментарий от r_asian

Ибо указатель занимает места, как правило, больше 1-го байта, да и не уверен я, что выделять нужное кол-во байт ручками - хорошая идея.

r_asian ★☆☆
()

На вскидку: строку 11 надо писать так: arr = (char **)malloc(5*sizeof(char*));

mr ★★
()

11	arr = (char *) malloc(5 * sizeof(char *));

13	arr[i] = (char *) malloc(100);

14	snpintf(arr[i], 100, "just it is a test %d", i); // боремся с переполнением буффера

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

s/11 arr =(char *) malloc(5 * sizeof(char *));/11 arr = (char **) malloc(5 * sizeof(char *));

Ex ★★
()

А у меня твой код нормально исполняется, никакого сегфолта.

gcc -v
Reading specs from /usr/local/lib/gcc/sparc-sun-solaris2.9/3.4.0/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --disable-nls
Thread model: posix
gcc version 3.4.0

shumer
()

Забыл sizeof(char *) в самом начале :/. Понял ошибку. Всем спасибо за помощь, вопрос снят.

anonymous
()
Ответ на: комментарий от Ex

> исполняется и не выпадает != правильный код

Это само собой. Только за то что не проверяет malloc надо двойку ставить. Но он пишет:

2) Происходит ошибка сегментации при освобождении памяти.

А нет никакой ошибки сегментации. Я удивился, что это вообще работает. Ругается только

warning: embedded `\0' in format

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

Правильный вариант:

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

#define LINES 5

int main()
{
        char** arr;
        int i;

        if(!(arr = malloc(LINES * sizeof(char*)))){
                fprintf(stderr, "Bad malloc\n");
                exit(1);
        }
        for(i = 0; i < LINES; i++){
                if(!(arr[i] = malloc(BUFSIZ * sizeof(char)))){
                        fprintf(stderr, "Bad malloc\n");
                        exit(1);
                }
                sprintf(arr[i], "just it is a test %d", i);
        }

        for(i = 0; i < LINES; i++)
                printf("arr[%d] = \'%s\'\n", i, arr[i]);

        for(i = 0; i < LINES; i++)
               free(arr[i]);
        free(arr);

        return 0;
}

shumer
()

Правильный ответ уже сказали, но довольно забавно видеть использование calloc(100, sizeof(char)); для выделения строки, и malloc - для массива: должно быть наоборот (нет смысла обнулять строку, только первый байт. С другой стороны, инициализировать указатель нулем очень даже полезно).

Кстати, sizeof(char) == 1 по определению, насколько я помню.

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