Arhn - архитектура программирования

Ошибка сегментации: указатель на массив строк

У меня есть массив строк (char **), который инициализируется как NULL. После передачи его адреса, когда я пытаюсь получить доступ к его элементам, возникает ошибка сегментации.

//following code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void parse(char ***test, char *str)
{
    int i;
    *test = (char**)malloc(sizeof(char*) * 3);
    for(i=0; i<3; i++)
    {
        *test[i] = (char*) malloc(sizeof(char)*(strlen(str)+1));
        strcpy(*test[i], str);
    }
}

int main(void)
{
    int i;
    char *str = "Hello world";
    char **test = NULL;
    parse(&test, str);
    for(i=0; i<3; i++)
        printf("%s\n", test[i]);
    return 0;
}

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


  • Нет необходимости приводить результат malloc() и друзей, да и не рекомендуется это делать никоим образом. 24.07.2015

Ответы:


1

*test[0] должно быть (*test)[i].

http://en.cppreference.com/w/c/language/operator_precedence говорит, что [] имеет более высокий приоритет, чем *, а это не то, что вам нужно.

Вы также не должны перезаписывать индекс 0.

sizeof(char) всегда равно 1, поэтому его можно не указывать. Вы также не должны приводить возвращаемое значение malloc и проверять на успех.

24.07.2015
  • Меня это никогда не поражало!! Удивительно. Большое спасибо! 24.07.2015

  • 2

    Проблема здесь

    *test[0] = (char*) malloc(sizeof(char)*(strlen(str)+1));
    

    вы всегда выделяете память для индекса 0.

    Кроме того, следуя таблице приоритета операторов, вам необходимо сначала разыменовать test, а затем примените индексацию к этому, поэтому вам в основном нужно переписать свой код, например

    (*test)[0]  = malloc( strlen(str) + 1);
    

    Пожалуйста, обрати внимание:

    1. Посмотрите, почему бы не привести возвращаемое значение malloc() и семьи в C.

    2. sizeof(char) гарантированно производит 1. Умножение на него избыточно.

    24.07.2015
  • это была опечатка!! Я отредактировал это!! Проблема все еще сохраняется! 24.07.2015
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..