Ошибка сегментации при попытке динамического выделения массива 2d char

Я написал следующий аналогичный пример, когда я получаю ошибку ошибки сегментации

{
    const char** var = NULL;
    const char* tmp = "Hello! How are you?";
    var = (const char**)malloc(5 * sizeof(char*));

    for (int i = 0; i < 5; i++)  
    {
        var[i] = (char*)malloc(50* sizeof(char));
        strcpy((char*)var[i], tmp);
    }
    for (int i = 0; var[i]; i++)
    {
        std::cout << (long int)var[i] << std::endl;
        std::cout << var[i] << std::endl;
    }
    // Free memory
    ....
    
}  

И на 6-й итерации цикл for не останавливается (я ожидал, что тогда var[i]==NULL), и я получаю ошибку «Ошибка сегментации». Можете ли вы объяснить, что я делаю неправильно, пожалуйста?

Где это крашится? Здесь помогает отладчик.

tadman 15.12.2020 10:09

Это тоже не Си. Похоже, что это C++, поэтому помечен соответствующим образом.

tadman 15.12.2020 10:10

Почему вы ожидаете var[6] == NULL?

Peter 15.12.2020 10:10

Как указал Питер, из вашей памяти может быть что угодно, не обязательно NULL.

Gabriel Pellegrino 15.12.2020 10:11

Намерение (long int)var[i] выполнить преобразование строки в целое число или представить этот указатель как число, просто чтобы посмотреть, что это такое?

tadman 15.12.2020 10:15

Почему varconst char**, а не просто char**? Эти const-приведения в вашем коде, по крайней мере, очень вводят в заблуждение (я бы сказал, ужасно).

Daniel Langr 15.12.2020 10:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это выходит за конец массива:

for (int i = 0; var[i]; i++)

Доступ к var за пределы — это поведение undefined, которое может привести к сбою. Вы не получите хорошего, аккуратного значения, когда превысите границы, как в JavaScript, Python или Ruby, у вас возникнут проблемы. К сожалению, для этого нет никаких проверок, поэтому вы должны быть бдительны, чтобы не сделать это непреднамеренно, ответственность лежит на вас.

Поскольку вы, по-видимому, используете С++, здесь можно многое исправить:

  • Не используйте массивы C, если можете этого избежать, используйте std::vector
  • Не используйте строки C, если можете этого избежать, используйте std::string

Сочетая этот совет, вы получаете:

const std::string tmp = "Hello! How are you?";

std::vector<std::string> var;

for (int i = 0; i < 5; i++) {
  var.push_back(tmp);
}

for (auto& v : var) {
  std::cout << v << std::endl;
}

// No need to free memory, it's already handled for you.

Когда вы пишете на C++, попробуйте и наслаждайтесь Стандартной библиотекой. Это значительно облегчит вашу жизнь, чем использование подверженных ошибкам методик C.

Но как я могу сделать это в стиле C?

Anton Golovenko 15.12.2020 10:39

Вы делаете это очень осторожно и никогда не выходите за пределы массива. Всегда следите за максимальным индексом, который вы можете использовать. Обычно это делается с помощью переменной size, хотя есть и другие способы, например, значения const. Это действительно зависит от контекста.

tadman 15.12.2020 10:40

Это как ехать по горной дороге с очень крутым обрывом с одной стороны и абсолютно без препятствий. Как не съехать с горы? Вы очень внимательно относитесь к тому, что делаете.

tadman 15.12.2020 10:43

Другие вопросы по теме