Jump to content
  • Advertisement
Sign in to follow this  
gamechampionx

C++ char** problem

This topic is 4496 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have the following C++.NET code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int *int_register;
char **string_register;
int *temp_int_register;
char **temp_string_register;

void main()
{
	//default to size of 1
	int_register = (int*)malloc(1 * sizeof(int));
	string_register = (char**)malloc(1 * sizeof(char*));
	//allocate all elements of string_register
	for(int i = 0; i < 1; i++)
	{
		string_register = (char*)malloc(255 * sizeof(char));
	}
	//set the first string to an empty string
	string_register[0] = '\0';
	//make int, string registers with size one more than current size
	//size extended from 1 to 2
	temp_int_register = (int*)malloc(2 * sizeof(int));
	temp_string_register = (char**)malloc(2 * sizeof(char*));
	//copy all pre-existing values
	for(int i = 0; i < 1; i++)
	{
		temp_int_register = int_register;
		temp_string_register = (char*)malloc(255 * sizeof(char));
		temp_string_register = string_register;
	}
	//malloc the individual string corresponding to the new element
	temp_string_register[1] = (char*)malloc(255 * sizeof(char));
	//set its value to the empty string
	temp_string_register[1] = '\0';
	//overwrite the old registers
	int_register = temp_int_register;
	string_register = temp_string_register;
	//set the second string to the empty string
	string_register[1] = '\0';
	//concatentaion error
	strcat(string_register[0],string_register[1]);
	printf("Press Enter to exit...");
	char temp_char;
	scanf("%c", &temp_char);
}

strcat is creating segmentation faults. Also, my IDE is complaining about the first for loop, saying that string_register is a <Bad Ptr>. I don't think what I'm doing is too far off (excluding memory leaks), so what's wrong with this code?

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
This code is bad:

string_register = foo;

.. because the string_register currently points to la-la land whenever i's value is greater than zero). Your IDE is probably complaining about that because it sees the , but doesn't go so far as to check that your for loop is hard-coded with a i <

Share this post


Link to post
Share on other sites
Quote:
Original post by gamechampionx
I have the following C++.NET code:


char **string_register;
...
//set the first string to an empty string
string_register[0] = '\0';


Code and comment doesn't match! string_register is a pointer to a pointer, which means string_register[0] is a pointer. To this pointer you assign the value zero, effectively a null pointer, making the first string point to null. the memory you allocated in the for-loop above is lost, since you reassign the pointer with a new value.

I suspect you want string_register[0][0] = '\0' instead, which will set the string string_register[0] to a zero length string.

Dunno if there are other problems, but I see some more similar errors further down the code.

edit: But an even more correct answer would be std::vector<std::string> string_register; and adapt the code thereafter.

Share this post


Link to post
Share on other sites
First I'll show you how to write code that achives the same effect using real C++ (since your code would more acurately be described as having been written in C.NET), then I'll walk you through the errors in your code as it stands.
// all singing, all dancing standard string class
#include <string>

// all signing, all dancing standard dynamic array class
#include <vector>

// google "C++ namespace" for details
using std::string;
using std::vector;

int main()
{
// a dynamic array of ints, intially one int
vector< int > int_register(1);

// a dynamic array of strings, intially one string
vector< string > string_register(1);

// resize the int array to hold two elements
// existing elements retain their old values
int_register.resize(2);

// resize the string array to hold two elements
// existing elements retain their old values
string_register.resize(2);

// concatenate the value of the second string onto the
// end of the first string
string_register[0] += string_register[1];
}



See how much easier and more readable that is?

Now, your version:
// In C++ the C headers X.h are renamed to cX
#include <cstdio>
#include <cstdlib>
#include <cstring>

// The updated headers put their symbols in namespace std
using namespace std;

int *int_register;
char **string_register;
int *temp_int_register;
char **temp_string_register;

// main must have a return type of int
int main()
{
//default to size of 1
// you'd usually use new in C++, not malloc
int_register = (int*)malloc(1 * sizeof(int));
string_register = (char**)malloc(1 * sizeof(char*));

//allocate all elements of string_register
for(int i = 0; i < 1; i++)
{
string_register = (char*)malloc(255 * sizeof(char));
}

//set the first string to an empty string
// you missed a level of indirection here
// you want to write to the first element of the first string
string_register[0][0] = '\0';

//make int, string registers with size one more than current size
//size extended from 1 to 2
temp_int_register = (int*)malloc(2 * sizeof(int));
temp_string_register = (char**)malloc(2 * sizeof(char*));

//copy all pre-existing values
for(int i = 0; i < 1; i++)
{
temp_int_register = int_register;
// you overwrite your malloc'd pointer here which is a memory
// leak. Just copy the pointer instead
//temp_string_register = (char*)malloc(255 * sizeof(char));
temp_string_register = string_register;
}

//malloc the individual string corresponding to the new element
temp_string_register[1] = (char*)malloc(255 * sizeof(char));

//set its value to the empty string
temp_string_register[1] = '\0';

// you missed the step of deallocating the old memory. Whatever you
// malloc you have to free
free(int_register);
free(string_register);


//overwrite the old registers
int_register = temp_int_register;
string_register = temp_string_register;

//set the second string to the empty string
// you missed a level of indirection here again
// you want to write to the first element of the second string
string_register[1][0] = '\0';

// this should now be fine - for this example at least
strcat(string_register[0],string_register[1]);

printf("Press Enter to exit...");
char temp_char;
scanf("%c", &temp_char);

// don't forget to deallocate, like I nearly did
free(int_register);
free(string_register[0]);
free(string_register[1]);
free(string_register);


}
Which is easier? The C solution or the C++ one?

Σnigma

Share this post


Link to post
Share on other sites
Darn it Enigma, I didn't see your reply, typed up one and you beat me too it. Nice job :)

@gamechampionx: If you're using tutorials or a book, get a newer one. That's not really C++ code that you posted. It would compile in a C++ compiler but like others said, it looks like it would compile in a C comipler also ;-)

Share this post


Link to post
Share on other sites
Thanks, the '\0' misassignment was the problem, and the code works once that is solved.

For reference, I misstated the setup of the code - the code itself is in classic C but I've generating it using a C++.NET program (this is part of a pseudo-compiler project), which partially explains why the code looks so terrible, lol.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
god thats some hideous code. I would destroy any coworkers that wrote shit like that.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!