Hello

I am in a question of assigning local scope pointers to global scope pinters.
I have a code like this.

public :
 char* myValue;

void process(TiXmlElement *element)
{
  myValue= element->getText();
}

But once the process function is returned value is garbage.

So I did this.

public :
 char* myValue;

void process(TiXmlElement *element)
{
  char* textVal = element->GetText();
  myValue= new char[sizeof(textVal)];
  memcpy(myValue, textVal, sizeof(textVal)); 
}

But still part of it is garbaged.
element->GetText() returnes "menustate" but when print 'myValue' it prints

menu²²²²♦

Could you plase tell me to do what.

Thank you

>>myValue= new char[sizeof(textVal)];
That won't work because sizeof(testVal) is nothing more than sizeof(char *), or 4 on most 32-bit compilers. What you want is myValue= new char[strlen(textVal)+1] then on the next line call strcpy() instead of memcpy().

Those two lines can be combined like this: myValue = strdup(element->GetText()); . To destroy the memory call free() instead of delete[] because strdup() is a C function that uses malloc().

Edited 6 Years Ago by Ancient Dragon: n/a

The idea in your second solution is the right one, you want to copy the memory from the string that is passed to a newly allocated string. That's exactly correct and proper. The only problem you have is that you used sizeof() to get the length of the string. This is not the right function. sizeof() is a "function" to give the size in memory of whatever variable or type you give it. In this case, the variable you give to sizeof() is textVal which is of type (char *) which is a pointer to a character, and on your system, a pointer has 4 bytes (32bit), so sizeof(textVal) will always give 4 (on your system). That's why you get 4 characters "menu" correctly copied to the new string, but the rest is gibberish.

The function to get the length of a string (C-style string, which is actually a pointer to the first char, of course) is the function strlen(). So, replacing sizeof() by strlen() will solve almost all the problem.

Another issue is that a C-style string has a null-character at the end to indicate the termination of the string. So the actual size you need to allocate for the new string is not strlen(), but strlen()+1, for the null-char. The same goes for the memcpy operation, also strlen()+1. You can also use strcpy() instead of memcpy().

Now, what happens if myValue already points to something? You need to check that it points nowhere or somewhere before allocating with new. If it does point somewhere, call delete[] before the new-statement.

Finally and most importantly, use std::string (in the <string> header) if you want to save yourself all the trouble in all of the above.

I have got an answer and a confirmation :)
Thank you very much to both of you. Both explanations helped me much.

But my compiler complaining me a warning saying strdup and strcpy both are deprecated.

So with the help of google search I have found this function.

static char* stringDuplicate(const char* str)
{
	char* value = (char*) malloc( strlen(str)+ 1);

	strcpy_s( value, strlen(str) + 1, str);
	return value;
}


// how i use it

myValue  = stringDuplicate(element->GetText());

free((void*)myValue);

This seems to fine
but please correct my if i am wrong here.

Thank you again

>>But my compiler complaining me a warning saying strdup and strcpy both are deprecated

The only compiler that complains about that is Microsoft. AFAIK they have not been deprecated in either the C or C++ standards. So I just use a pargma to remove that warning #pragma warning(disable: 4996)

Yeah, that's true, some compilers consider pretty much any C functions as deprecated (which includes all the functions that operate on C-style strings, i.e., char*). The code you posted just there is quite alright, in the sense that it's just an exact replica of the original strdup() function. It is a good idea to get rid of any warnings like "deprecated", because, although they are often benign, they sometimes hide a real problem and even just reimplementing the simple function like you did there is a bit safer.

But still, repeating my last point in my original post, in C++, if you want to completely avoid "deprecated" stuff, just use C++ standard libraries (including std::string) and no C libraries at all (besides maybe <cmath>). The only reasons I know to use C libraries is if you don't have a choice (like a weird / old platform) or would just like to first get a grip on the basic C mechanisms that are somewhat fundamental to C++ (which can be quite beneficial).

EDIT: Just saw AD's post: No.. please.. don't disable warnings.. always compile with all warnings and make sure to get rid of them all. I know Microsoft's compiler is particularly nagging, but still, treat warnings as errors because they often hide a subtle one.

Edited 6 Years Ago by mike_2000_17: n/a

>>EDIT: Just saw AD's post: No.. please.. don't disable warnings.. always compile with all warnings and make sure to get rid of them all. I know Microsoft's compiler is particularly nagging, but still, treat warnings as errors because they often hide a subtle one.

In most (all other) cases I would agree with you. But the C functions are not depreciated by either C or C++ standards, and that's the only ones that count. Microsoft does not set the standards, even though they may be a major contributor. I don't mean to say there is anything wrong with using strcpy_s() instead of strcpy(), just that strcpy() is more convenient and can be just as safe.

There are a number of instances where character arrays are more convenient than std::string. structures, binary files, databases, and socket programming are just a few of them.

>>But the C functions are not depreciated by either C or C++ standards, and that's the only ones that count.

I beg to differ, the implementers (or authors of the run-time libs) also count when it comes to deprecated functions. If the standard says a function is deprecated, it just means the lib implementers are no longer required to provide that function and might not, and that's why you need to avoid them even if your platform still has them. But MS compiler warnings about deprecated functions go the other way too, it can mean that the function is there because the standard requires that function to be there, but the implementer warns you that it might not be wise to use it.

Microsoft provides the C run-time libraries for its OS and it can happen that some of its functions, although kept to conform with standards, can have some hidden issues. MS calls them "security" issues, like they call everything else a "security issue" or "security update" or "security feature"... when really what they mean is they had screwed up the implementation before and now they "fixed" it, i.e. "more secure" as in "less chance of crashing", but now they are stuck with an old, backward-compatible version they don't recommend you use, without admitting it has a bug (and thus, marking it as deprecated).

I've had that problem in the past.. yes it can cause a real problem, it is not just a theoretical thing. It was years ago and I don't remember which function it was (one of those C functions that insidiously wraps a memory allocation). But I know I spent a LONG time looking for the bug (I mean months!), thinking deprecated functions were nothing to worry about, until I found a fine print on msdn (wish I could find it again!) that said one of those deprecated functions had something like only a "probable behavior", but no guaranteed behavior. In my case, it corrupted the heap: replacing it with a non-deprecated version fixed the problem.

I don't want to digress this thread any further... so lets just say, you can keep ignoring the deprecated functions in the windows CRT if you want, but if you find yourself with a really bad bug on your hands and have tried everything else, maybe replacing all the deprecated function calls could help. Of course, you wrap any non-standard function call in a preprocessor conditional, that goes without saying.

Final thought, sure you can use char arrays sometimes, i.e. "when you have no choice", and, with a stretch of the imagination, they might even be more convenient sometimes, but I still would not use any of the C functions that wrap memory allocations (so maybe sprintf, strcpy, strcmp, etc. are OK).

This article has been dead for over six months. Start a new discussion instead.