# Problems with char*

## Recommended Posts

I have been using char* as a string, but I am having a problem. I will just try to explain it using code:
//I am writing this off the top of my head, to show my problem:
int g_SomeInt = 0;
char* g_Text = "";

void SomeFunctionCalledOncePerFrame()
{
char String[512];
g_SomeInt++;
sprintf(String,"Number:  %i",g_SomeInt);
SomeFunction(String);
}

void SomeFunction(char* Text)
{
if (g_Text == Text)
return;

//some more code

g_Text = Text;
}


g_Text is supposed to store the text from the last time the function was called, so when the Text supplied to the function changes, it is not supposed to return, however, it always returns (except for the first time). I think I may know why, because g_Text is a char*, it is actually a pointer, so it is pointing to the Text, so when the text changes, g_Text changes as well, and therefore, g_Text will always equal Text. What is the best way around this? No matter what I try, g_Text is always equal to Text. I REALLY don't want to use a char array because then it would have to be a specified size, and the text supplied to this function varies dramatically. Any help is appreciated, -Dev578

##### Share on other sites
Hmm, so what exactly are you trying to do? If you explain your intention then I can help...

Your code contains a few problems:
1. As soon as SomeFunctionCalledOncePerFrame() is exitted, the string pointed to by g_Text doesn't exist anymore...
2. Why do this?
char* g_Text = ""

Its just a waste of the data segment.

##### Share on other sites
If you're using C++:
int g_SomeInt = 0;std::string g_Text = "";void SomeFunctionCalledOncePerFrame(){	SomeFunction("Number: " + boost::lexical_cast< std::string >(++g_SomeInt));}void SomeFunction(std::string const & text){	if (g_Text == text)	{		return;	}	//some more code	g_Text = text;}

Else:
int g_SomeInt = 0;char * g_Text = 0;void SomeFunctionCalledOncePerFrame(){	char string[std::strlen("Number: ") + MAX_DIGITS_IN_INT + 1];	sprintf(string, "Number: %i", ++g_SomeInt);	SomeFunction(string);}void SomeFunction(char const * const text){	if (g_Text && strcmp(g_Text, text) == 0)	{		return;	}	//some more code	free(g_Text);	g_Text = strdup(text);}

Or something like that.

Enigma

##### Share on other sites
First, g_Text == Text compares the addresses of the strings involved not the content. Second, g_Text = Text makes (as you said) g_Text point to the memory location that Text points to (considering that Text is a local variable this is extremely bad).

Either use std::string or use the appropriate functions. That's strcmp and strcpy. However, using these functions requires you to allocate enough memory to hold the string in g_Text which you are currently not doing.

##### Share on other sites
You need to learn how the stack works.
The stack is a special reserved memory in which all local variables and arguments are stored temporarily. 'char String[512]' is a local char array which will be stored on the stack. When the function returns this stack memory is freed, and ready to be used by other functions.

If you make g_Text point to an address on the stack you never know what it will contain, because every function you call use that memory for its own variables.

What you should do is allocate separate memory for g_Text when you need it.

#include <malloc.h>#include <string.h>char* g_Text = NULL;void SomeFunction(char* Text){    if(g_Text != NULL)        free(g_Text);  // Free the memory previously allocated    g_Text = (char *)malloc(strlen(Text) + 1);  // Allocate new memory    strcpy(g_Text, Text);  // Copy the entire string too g_Text}

Now g_Text will be allocated with the amount of space that is needed to store the string.

##### Share on other sites
I highly recommend you use std::string if you're using C++!

Back to your problem, when you write g_Text == Text you are actually comparing pointers. What you actually need to do is to compare the strings, so you need to use strcmp. Also, at the end of SomeFunction, you're not doing what you think you are! You are actually assigning g_Text to point to the location of String (which is VERY bad, as String is a local variable. What you need to do is allocate g_Text some memory (using strlen to ge the string's length) AFTER you've checked to see if g_Text has already had some memory assigned. Then use strncpy to copy the string over.

Here's some code, but as you can see, there is a lot to do, which is why I recommend using a std::string
#include <cstddef>#include <string.h>int g_SomeInt = 0;char * g_Text = 0; //We are going to assign to it later!void SomeFunctionCalledOncePerFrame(){	g_SomeInt++;	char String[512];	sprintf(String, "Number:  %i", g_SomeInt);	SomeFunction(String);}void SomeFunction(const char * Text) //I'm sure you just missed off the const ;){	if (g_Text) //We may of not yet allocated g_Text	{		if (strcmp(g_Text, Text) == 0) //They match			return;	//some more code	}	delete g_Text; //Remember, it's safe to delete null pointers - no need to check for NULL!!	std::size_t stringLength = strlen(Text) + 1; //+1 for null terminator (can't remeber if it's needed, but best be safe!)	g_Text = new char[stringLength]; 	strncpy(g_Text, Text, stringLength);}

Now, for intrest, lets compare it with std::string

#include <cstddef>#include <sstream> //std::istringstream#include <string> //No ".h"//I am writing this off the top of my head, to show my problem:int g_SomeInt = 0;std::string g_Text;void SomeFunctionCalledOncePerFrame(){	std::istringstream buffer;	buffer << "Number:  " << ++g_SomeInt;	SomeFunction(buffer.str());}void SomeFunction(const std::string & Text) //Can also pass in a char *, such as "Hello world"!{	if (g_Text == Text) //std::string has comparison operators!          return;	//some more code	g_Text = Text; //How easy was that??}

Code has not been tested!

##### Share on other sites
With c style strings, you're supposed to do the following:
/* We need functions */#include <string.h>/* Allocate space. */#define BUFFER_SIZE 256char g_Text[ BUFFER_SIZE ];/* And a test function */int do_something(){  strncpy( g_Text, "Its a cool thing.", BUFFER_SIZE );  g_Text[ BUFFER_SIZE - 1 ] = 0;  return 0;}

See, you don't assign c-styled strings. You COPY c-style strings. Make sure you always have enough memory assigned, and although everyone likes strcpy because its faster, I like strncpy because its safer, no segmentation faults.

##### Share on other sites
Quote:
 Original post by desertcubeI highly recommend you use std::string if you're using C++!

And if you're not using C++, I suggest you consider starting. Most C code will compile with a C++ compiler, and you can continue to do almost everything the way you do it in C, with the additional ability to use std::string and std::vector (for arrays).

##### Share on other sites
Quote:
 Original post by Will FAnd if you're not using C++, I suggest you consider starting.

I highly recommend that you don't start using C++ until you've mastered the basics of imperative programming with C. C's hard to learn for a beginner, C++ is harder..

Good luck.

##### Share on other sites
std::string my_string = "asd";std::string other_string = my_string+"l";//is much easier to learn than// the ugly C sortof-equivalentchar my_string[] = "asd";char other_string[16];strncpy( other_string, my_string, 16 );strncat( other_string, "l", 16 - strlen(other_string) );

Stroustrup has a nice paper on the topic: http://www.research.att.com/~bs/new_learning.pdf .

##### Share on other sites
me22: Thanks for the link, I was speaking from my experiences.

OFF TOPIC (sorry OP)

The problem with this

std::string my_string = "asd";std::string other_string = my_string+"l";

is that there are many mechanisms going on that aren't shown. Hence understanding how this actually works is, imho, more difficult, but necessary to be able to use the features of C++.
Eg.. the user might see this code and then attempt to do something like this:

std::string helloString = "hello" + "there";

Which (according to my compiler) will not compile:
test.cpp: In function int main()':test.cpp:7: error: invalid operands of types const char[8]' and const char[4]' to binary operator+'

Now ask the user why that is, and because of your string ADT abstraction, he/she will not have a clue. That's the problem with C++ as a first language.

##### Share on other sites
try this one......

int g_SomeInt = 0;char* g_Text = new char[1]; // previously char* g_Text = "";void SomeFunctionCalledOncePerFrame(){     char String[512];          g_SomeInt++;     sprintf(String,"Number:  %i",g_SomeInt);     SomeFunction(String);}void SomeFunction(char* Text){     if (strcmp(g_Text,Text)==0)          return;          //some more code     // g_Text = Text; is replaced with the codes below     // delete previous contents of g_Text     // create g_Text with Text's size (plus 1 for the null terminator)     // copy contents of Text to g_Text     if(g_Text)      {         delete [] g_Text;         g_Text = NULL;      }     int i = strlen(Text)+1;     g_Text = new char[i];     strcpy(g_Text,Text);}