Hello, I am having trouble with arrays.
Basically, this is what happens:

vector <char*> constArray(10);
char* changingString = "hello";

constArray[0] = changingString;
changingString = "hi";

printf("constArray[0] = %s\nchangingString = %s", constArray[0], changingString);

Output:
constArray[0] = hi
changingString = hi

So, I think constArray[0] is changing because it points to the same location as changingString. My problem is, how do I force constArray[0] NOT to change when changingString is altered?

Dani AI

Generated

Short answer: assigning a char* into the vector copies the pointer, not the characters behind it. That means the vector element and your original buffer both reference the same memory. In this thread the confusion came from two different cases: a pointer to a string literal (reassigning the pointer moves it) versus a pointer into a mutable stack buffer (writing into that buffer changes what every pointer sees). later clarified the second case, which is what caused the observed behavior.

To make an independent copy you must allocate storage and copy the bytes, or use a type that does that for you. Be explicit about ownership: if you allocate with new[] you must free with delete[]; if you obtain memory from strdup you must free() it. Deleting memory you did not allocate (stack arrays or string literals) is undefined behaviour. See the C++ delete rules and automatic storage lifetime for details (delete operator, automatic storage duration).

Prefer higher-level types to avoid manual mistakes. Storing std::string in a std::vector makes copies and manages lifetime for you; std::unique_ptr<char[]> is an option if you really need raw buffers. Be cautious with non-owning views (e.g., string_view) because they can dangle if the original buffer goes out of scope (std::string, std::vector).

Practical debugging tips: print pointer addresses to confirm whether two variables point to the same buffer, run a leak checker (Valgrind) to spot lost allocations, and always allocate room for the terminating NUL. had the correct approach of copying the buffer; ’s new then immediate overwrite is the common leak pattern to avoid.

Recommended Answers

All 9 Replies

vector <char*> constArray(10);
	char* changingString = "hello";

	constArray[0] = new char;
	constArray[0] = changingString;
	changingString = "yadayada";

	printf("constArray[0] = %s\nchangingString = %s\n", constArray[0], changingString);

Well you got a strange compiler, mine outputs hello, hi...
the constArray[0] points to the static string "hello", if you want to point at the pointer pointing to hello you gotta do &p...
allocating a new char is just a memory leak since the pointer gets overwritten in the next operation (se above post).

Well you got a strange compiler, mine outputs hello, hi...

Yeah I just ran it. So does mine.

allocating a new char is just a memory leak since the pointer gets overwritten in the next operation (se above post).

yeah thought as much. Anyway got the desired output ( but i know it is bad code). Tried calling delete on it, but that does not also work. Why is that?

delete what?
(this should work, included some possible errors I could think of)

vector <char*> constArray(10);
	char* changingString = "hello";

        delete constArray[0] ; // error, not initated (I can never remember if deleting 0 is an error or not, so I usually dont) 
        // the vector initates all elements with default constructor, however 
        // I dont remember if default constructor for pointers actually does anything since they are built in types (optimization)
        // testing this results in only zero values but that is
        // likely due to using dynamic memory (which mostly is zero before use, since it get cleared when the process is handed it...
        // for stack variables crapp exists in variables after skipping initation... (enough of ranting, stopping now)...
	constArray[0] = new char;
        delete constArray[0] ; // this is ok, we just gave it a pointer to a char
        delete [] constArray[0] ; // error, did not allocate an char string, only a single char
	constArray[0] = changingString;
        delete [] constArray[0] ; // error, not dynamically allocated
	changingString = "yadayada";
allocated

Sorry, the example I gave must have been incorrect; I hadn't tested it. The thing that is wrong with my example is that changingString is an array rather than a character pointer. This is more accurate:

#include <vector>
#include <stdlib.h>
using namespace std;

vector <char*> msgs(100);

int main(){
	char changingString[200];
	memcpy(changingString, "hello", 6);
	int numMsgs = 0;

	msgs[numMsgs] = changingString;
	memcpy(changingString, "hi", 3);

	printf("msgs[%d] = %s\nchangingString = %s", numMsgs, msgs[numMsgs], changingString);

	return 0;
}

My output:
hi
hi

Anyone know how to change this? I tried setting msgs[0] to new char, but that didn't work...

Sorry, the example I gave must have been incorrect; I hadn't tested it. The thing that is wrong with my example is that changingString is an array rather than a character pointer. This is more accurate:

#include <vector>
#include <stdlib.h>
using namespace std;

vector <char*> msgs(100);

int main(){
	char changingString[200];
	memcpy(changingString, "hello", 6);
	int numMsgs = 0;

	msgs[numMsgs] = changingString;
	memcpy(changingString, "hi", 3);

	printf("msgs[%d] = %s\nchangingString = %s", numMsgs, msgs[numMsgs], changingString);

	return 0;
}

My output:
hi
hi

Anyone know how to change this? I tried setting msgs[0] to new char, but that didn't work...

if you were to do printf("%p == %p ?\n", changingString, msgs[numMsgs] ) You would find that both pointers are identical... Either create a new string and copy the value over

msgs[numMsgs] = new char[ strlen( changingString ) + 1 ]; 
strcpy( msgs[numMsgs], changingString ) ;

or use stl strings

std::vector< std::string > msgs(size) ;
...
msgs[numMsgs] = changingString ;

This will also copy the data and not just the pointer.

Thanks for that information, perniciosus. I will try that as soon as I can get a compiler handy :P

msgs[numMsgs] = new char[ strlen( changingString ) + 1 ]; 
strcpy( msgs[numMsgs], changingString ) ;

or use stl strings

std::vector< std::string > msgs(size) ;
...
msgs[numMsgs] = changingString ;

Neither of these work.... The latter makes the text very weird (some weird character, a black smiley face, and an 8, rather than the text "hello") and the former has the same result as what previously was happening, where if changingString is altered, so is msgs[x].

Oh! Nevermind, I fixed my error. Perniciosus, you were correct. I had been so focused upon the "strlen(changingString) + 1" part that I forgot about the strcpy. Now it works. Sorry for the three posts in a row, but they are on three subjects and it would have been weird to make a statement and disagree with it in the same post :P.

Thanks perniciosus!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.