1

I need to populate a vector variable from a char** variable that i get from another function.

I tried on my own the following program:

#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
char** getS();
int main()
{
    int i;
    vector<string> a;
    cout << "Hello World" << endl; 
    char** b=getS(); 
    char c[][5] = {"one","two","thr"};


    //a.insert(a.begin(), b, b+3);

    for(i=0;i<3; i++)
    {
        a.push_back(b[i]);
    }


    for(i=0;i<3; i++) 
        free(b[i] );

    free(b); 

    for(i=0;i<3; i++)
    {
        cout <<a[i].c_str() << endl; 
    }
    return 0;
}

char** getS()
{
    char** list; 
    int number_of_row=3,number_of_col =5,i;
    list = (char**)malloc(sizeof(char*)*number_of_row);
    for(i=0;i<number_of_row; i++) 
    {
        list[i] =(char*) malloc(sizeof(char)*number_of_col);  
        list[i] ="Hello";
    }

    return list;
}

I tried executing it in the this site.

I am getting an invalid pointer error and a dump in console. But I believed pointers can be freed as i did above after pushing the values into a vector. If i remove the freeing of pointer b then the code works fine.

I need to use this vector after freeing the original char** variable from which it was populated.

length of the string array in char** is hardcoded in my example.

Andrei Bârsan
  • 3,473
  • 2
  • 22
  • 46
Mohamed Iqzas
  • 976
  • 1
  • 14
  • 19
  • 2
    You have a vector of string yet you malloc char*, why!?! – Borgleader Jan 06 '15 at 15:31
  • Looks like you are trashing your memory with `list[i] ="Hello";`. `"Hello"` actually requires 6 characters and you only sized the array for 5. – NathanOliver Jan 06 '15 at 15:32
  • 2
    Who ever teaches you to write C++ like this, hit him in the head with a [real book.](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) (Or at least get one for yourself, using `malloc` like this is a baaad idea for example.) – Baum mit Augen Jan 06 '15 at 15:33
  • the main aim of this sample code is to test whether freeing up of pointers, after converting a char** into a vector, works fine. Thanks for pointing out other issues with the code. – Mohamed Iqzas Jan 07 '15 at 07:48

1 Answers1

9

The problem is this line:

list[i] ="Hello";

This doesn't copy the string into the memory you have allocated, it overwrites the pointer. After that statement, you have lost the pointer you have allocated, and instead made it point to a string literal (which is allocated statically by the compiler, and should not be free'd by you). If you insist using character pointers you should use std::strcpy to copy the string contents.


However, you are programming in C++, so why are you even bothering with pointers? You have std::vector, you have std::string, use them all through your program and you will not have problems like this.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    Exactly. You're not allowed to `free()` static strings and you get a segmentation fault if you try to. Secondly, I'd also like to point out that mixing C++ containers and `char**` is not a good idea unless you really know what you're doing (e.g. interoperability with C code), and you should use `std::string` whenever possible. – Andrei Bârsan Jan 06 '15 at 15:36
  • Use strdup to duplicate a string in C. Prefer std::string in C++. – dascandy Jan 06 '15 at 15:40
  • @Joachim: can you please tel me whether the commented line a.insert(a.begin(), b, b+3); is better than the for loop for populating the vector? – Mohamed Iqzas Jan 07 '15 at 07:52