Anton Golovenko
Anton Golovenko

Reputation: 644

Segmentation fault when trying dynamically allocate 2d char array

I have written the next similar example when I get a segmentation fault error

{
    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
    ....
    
}  

And on the 6th iteration, for loop doesn't stop (I expected then var[i]==NULL) and I get the "Segmentation fault" error. Can you explain what I am doing wrong, please?

Upvotes: 1

Views: 66

Answers (1)

tadman
tadman

Reputation: 211740

This walks off the end of the array:

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

Accessing var out of bounds is undefined behaviour, which can lead to a crash. You won't get a nice, neat value when you exceed the bounds like you might in JavaScript, Python or Ruby, you get problems. Unfortunately there's no checks for this, so you must be vigilant about not doing it inadvertently, the responsibility is on you.

Since you're apparently using C++ there's a lot of things you can fix here:

  • Don't use C arrays if you can avoid it, use std::vector
  • Don't use C strings if you can avoid it, use std::string

Combining this advice you get:

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.

When you're writing C++, try and enjoy the Standard Library. It will make your life significantly easier than leaning heavily on error-prone C techniques.

Upvotes: 4

Related Questions