Вызвано исключение в c++

285
15 января 2018, 09:05
#include "stdafx.h"
#include <iostream>
//Функция заполнения массива
void fill_array(char arr[13], const char *info = "fill_array\n") {
    std::cout << info;
    for (int i = 0; i < 13; i++) arr[i] = info[i];
}
int main()
{
    char info[] = "dong!";
    std::cout << info << std::endl;
    fill_array(info);
    std::cout << info << std::endl;
}

Этот код вызывает ошибку:

Run-Time Check Failure #2 - Stack around the variable 'info' was corrupted.

Почему оно переполняет стек?

Answer 1
char info[] = "dong!";

info - это массив из 6 элементов.

for (int i = 0; i < 13; i++) arr[i] = info[i];

Вы же пытаетесь переписать 13 элементов, в результате чего выходите за пределы массива и портите данные в стеке.

Answer 2
//#include "stdafx.h" Закомментировал, поскольку мне оно не требуется - использую GNU/Linux
#include <iostream>
#include <cstring> // Требуется для strlen. По факту, C-строки лучше не использовать. Вместо них - std::string из заголовочного файла `string`
void fill_array(char* arr, const char *info = "fill_array\n") {
  // Функция заполнения массива
  std::cout << info;
  for (int i = 0; i < strlen(info); i++)
    arr[i] = info[i];
}
int main() {
  char info[13] = "dong!"; // Компилятор выделяет под этот массив 6 байт - под `dong!` и под терминальный символ '\0'. Этого не хватает, что-бы скопировать туда строку из 13 байт.
  std::cout << info << std::endl;
  fill_array(info);
  std::cout << info << std::endl;
}
Answer 3

Вы наткнулись на подводный камень с передачей массива в функцию. Дело в том, что в этом случае тип аргумента функции деградирует до char * полностью игнорируя указанный размер массива. Реально функция выглядит вот так:

void fill_array(char * arr, const char *info = "fill_array\n") {
   std::cout << info;
   for (int i = 0; i < 13; i++) arr[i] = info[i];
}

Ну а передавая в нее char info[] (имеющий размер 6 байт) вы прямо осуществляете переполнение.

Выводов можно сделать два:

  • в сигнатуре функций никогда не должно быть массивов;
  • при передаче в функцию указателя на данные для записи всегда должен передаваться размер буфера, на который он указывает;
Answer 4
    int main()
{
char info[] = "dong!";
cout << info << endl;
fill_array(info, "fill"); // так будет работать
cout << info << endl;
}
READ ALSO
Что делают функции begin() и end()

Что делают функции begin() и end()

Нигде не могу найти описание функций begin() и end(), для чего они нужны? Если можно напишите пример пожалуйста :)

316
Для чего нужен static_cast, как он работает и где его применяют?

Для чего нужен static_cast, как он работает и где его применяют?

У static_cast очень много различных примененийЕго идея состоит в следующем: это ограниченный по мощи C-style cast

334
Максимальный обьем кучи С++

Максимальный обьем кучи С++

Какой максимальный обьем кучи? Если у стека приблизительно: 4 MB?

235
Работа с std::vector в С++

Работа с std::vector в С++

Задача состоит в следующем:

285