Reputation: 55
This is my code and I want to return 2D dimension array [10][8] and [10][20] from my function, but i get an error !! (Segmentation fault).
Please help me !! I need this for my project. Finally i want to print this array and I cant do this because of the error.
Can someone help me fix this and print that?
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
char **getWords(int level)
{
if (level == 1)
{
char **words = new char *[8];
strcpy(words[0], "Pakistan");
strcpy(words[1], "Portugal");
strcpy(words[2], "Tanzania");
strcpy(words[3], "Thailand");
strcpy(words[4], "Zimbabwe");
strcpy(words[5], "Cameroon");
strcpy(words[6], "Colombia");
strcpy(words[7], "Ethiopia");
strcpy(words[8], "Honduras");
strcpy(words[9], "Maldives");
return words;
}
//For Hard Level
else if (level == 2)
{
char **words = (char **)malloc(sizeof(char *) * 20);
strcpy(words[0], "Tajikistan");
strcpy(words[1], "Uzbekistan");
strcpy(words[2], "Azerbaijan");
strcpy(words[3], "Bangladesh");
strcpy(words[4], "Luxembourg");
strcpy(words[5], "Madagascar");
strcpy(words[6], "Mauritania");
strcpy(words[7], "Montenegro");
strcpy(words[8], "Mozambique");
strcpy(words[9], "New Zealand");
return words;
}
}
int main()
{
getWords(1);
return 0;
}
Upvotes: 1
Views: 561
Reputation: 23832
By doing
char **words = new char *[10];
You are only allocating memory for the pointers, not for the memory blocks where the actual strings are to be stored, you need to allocate memory for that too:
char **words = new char *[10]; //space for 10 pointers
for(int i = 0; i < 10; i++){
words[i] = new char[10]; // space for 10 characters each line, 8 is not enough
} // you need at least 9 because of the ending nul byte
strcpy(words[0], "Pakistan");
strcpy(words[1], "Portugal");
//...
In main, assing them to a pointer to pointer and print them as if it was an array of strings:
char** words = getWords(1);
for(int i = 0; i < 10; i++){
std::cout << words[i] << std::endl;
}
The same goes for the second part which uses malloc
.
char **words = (char**)malloc(sizeof *words * 10); //space for 10 pointers
for(int i = 0; i < 10; i++){
words[i] = (char*) malloc(20); //space for 20 characters each line
}
In a normal situation, when the program doesn't end right away you would have to free the memory:
For memory allocated with new
:
for (int i = 0; i < 10; i++)
{
delete words[i];
}
delete words;
For the memory allocated with malloc
:
for(int i = 0; i < 10; i++)
{
free(words[i]);
}
free(words);
This can be tricky in your case because you return 2 types of memory allocation deppending on the option you pass as parameter, my advice is that you use that same option to choose how to deallocate the memory.
P.S.: Using C++ containers like std::vector
and std::string
would make your job easier, you wouldn't need to handle the memory yourself.
Upvotes: 2
Reputation: 206717
Use of
char **words =new char*[8];
strcpy(words[0],"Pakistan");
is a problem since you have not allocated memory for words[0]
.
It's analogous to
char* cp; /// Uninitialized pointer
strcpy(cp,"Pakistan");
You'll have to allocate memory for words[0]
, words[1]
, etc. before you use them in the call to strcpy
.
More importantly, change your strategy, and use std::vector<std::sting>
instead. That makes your code simpler and removes the burden of allocating and dealloating memory from application code.
std::vector<std::string> getWords(int level)
{
std::vector<std::string> words;
if (level==1)
{
words.push_backl("Pakistan");
// etc.
return words;
}
Upvotes: 1