Wiriting Through Free Store Pointers

So I was wondering. Well, let me show you the (shortened) code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
char* devowel(const char* orig)
{
        //Omitted for brevity
  	//Resize
	removed_copy = removed;
	count = 0;
	while (*removed_copy++) ++count;

	removed_copy = removed; //You think it's because it's no longer pointing to first spot?

	char* resized{ new char[count + 1] };
	char* resized_copy{ resized };

	while (*removed_copy) *resized_copy++ = *removed_copy++;
	*resized_copy++ = 0;

	delete[] removed; //Here is the problem

	return resized;
}


The part you're missing is really just passing a string, copying it to the free store, then copying the rest to a resized free store char pointer and passing it back.

The code abode works - not an issue. The issue is that if I try to write through the ACTUAL free store pointer (NOT the copy) I get garbage when I print it. When I write through the pointer TO the free store allocated pointer, it works.

What am I missing here?

Also, while I'm here, am I to assume that changing the position of a free store pointer makes deleting it erroneous? Because that happened too...

EDIT: ^ That's why the comment about it pointing to the right spot comes from. I was using removed everywhere you see removed_copy now, and it was all problems.
Last edited on
The code abode works - not an issue. The issue is that if I try to write through the ACTUAL free store pointer (NOT the copy) I get garbage when I print it. When I write through the pointer TO the free store allocated pointer, it works.
What is the 'free store pointer'.

You cannot use removed_copy or removed after line 17.

You omitted the relevant part of the code. It should contain main() and a way to reproduce the problem. It should also be compilable.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
char* devowel(const char* orig)
{
	//Get count, copy orig, reset copy
	const char* orig_copy{ orig };
	int count{ 0 };
	while (*orig_copy++) ++count;
	orig_copy = orig;

	//Allocated to count + 1, copy that
	char* removed{ new char[count + 1] };
	char* removed_copy{ removed };

	//Vowels array, point to it
	char vowels[]{ "AaEeIiOoUu" };
	char* v_pointer{ vowels };

	bool not_vowel{ true };

	//Test orig against vowels
	while (*orig) { //Missing star?! Replace orig with orig_copy
		while (*v_pointer) {
			if (*orig == *v_pointer) {
				not_vowel = false;
				break;
			}
			++v_pointer;
		}
		v_pointer = vowels;
		if (not_vowel) *removed_copy++ = *orig;
		not_vowel = true;
		++orig;
	}
	*removed_copy++ = 0;

	//Resize
	removed_copy = removed;
	count = 0;
	while (*removed_copy++) ++count;

	removed_copy = removed; //You think it's because it's no longer pointing to first spot?

	char* resized{ new char[count + 1] };
	char* resized_copy{ resized };

	while (*removed_copy) *resized_copy++ = *removed_copy++;
	*resized_copy++ = 0;

	delete[] removed; //Here is the problem

	return resized;
}

int main()
{
	char unvowel[]{ "Just a string that needs unvoweling" };
	char* diditwork{ devowel(unvowel) };
	print_str(diditwork);
}


print_str() is really just a simple print function.
I'm putting this in another message because it's worth noting that's the CORRECT code. THAT code works. However, anywhere I used the original (AKA everything _copy) I had problems.
I appreciate it and all, but the problem is that my version DOES work... kind of. Let me try again...

Suppose I create something on the free store like above, and want to write to it:

1
2
3
4
5
6
7
char* forExample{new char[size + 1]};
while(*passedParameter){
*forExample++ = *passedParameter++;
}

*forExample++ = 0;
return forExample;


This won't work for me. It will only print garbage. HOWEVER...

1
2
3
4
5
6
7
8
9
char* forExample{new char[size + 1]};
char* forExampleCopy{forExample};

while(*passedParameter){
*forExampleCopy++ = *passedParameter++;
}

*forExampleCopy++ = 0;
return forExample;


This WILL work, and work correctly, and I'm not understanding why.

All I can ASSUME is that it's because of the same reason I SUSPECT calling delete[] on a pointer to free store memory also returns an error - it has been incremented, and thus isn't pointing to element 0.

I don't know. I just don't understand, and the book never REALLY gets into the dynamics behind it (Programming Principles and Practice). Take an except from above:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	//Test orig against vowels
	while (*orig) { //Missing star?! Replace orig with orig_copy
		while (*v_pointer) {
			if (*orig == *v_pointer) {
				not_vowel = false;
				break;
			}
			++v_pointer;
		}
		v_pointer = vowels;
		if (not_vowel) *removed_copy++ = *orig;
		not_vowel = true;
		++orig;
	}
	*removed_copy++ = 0;


Before (when I didn't care what the size was) I used:

1
2
3
while(orig){
//all the above
}


But that failed EVERY SINGLE TIME, and you can bet I ran it while shouting profanity numerous times. But when I dereferenced it:

1
2
3
while(*orig){ //That star!
//all the above
}


No problems! I took that to mean they (pointers) DEFINITELY don't know where their end is, EVEN WHEN PASSED AS A "C-STYLE" STRING:

1
2
        char unvowel[]{ "Just a string that needs unvoweling" };
	char* diditwork{ devowel(unvowel) };


Sorry. I'm just getting a bit frustrated with it is all, and it ALWAYS happens when I return to C-Style strings. Maybe the point wasn't to just help me understand them, but gain appreciation for the vector and string classes? Mission THOROUGHLY accomplished, and I've long refused to use them, but I DO want to understand them...
This won't work for me. It will only print garbage. HOWEVER...
The reason for the garbage is the pointer at the wrong position:
1
2
3
4
5
6
7
char* forExample{new char[size + 1]};
while(*passedParameter){
*forExample++ = *passedParameter++;
}

*forExample++ = 0;
return forExample; // Note: due to the line(s) above it points past the end 


Here you have extra code to keept the pointer at the beginning of the string:
1
2
3
4
5
6
7
8
9
char* forExample{new char[size + 1]};
char* forExampleCopy{forExample};

while(*passedParameter){
*forExampleCopy++ = *passedParameter++;
}

*forExampleCopy++ = 0;
return forExample; // This is ok because the pointer is at the beginning of the string 


Consider this:
1
2
3
4
5
6
7
8
char* forExample{new char[size + 1]};
int i = 0;
for(; passedParameter[i]; ++i){
forExample[i] = passedParameter[i];
}

forExample[i] = 0;
return forExample; // Note: the pointer did not move 
Yeah man, that's EXACTLY what I was wondering, but I wasn't sure.

I guess I was thinking that the pointer could change its positioning, but that it would "remember" its original position. Like, if I played with it a bit:

1
2
3
char* AboutToCauseTrouble{new char[10]};
AboutToCauseTrouble++;
delete[] AboutToCauseTrouble; //Here's trouble... 


The program would assume (and was I ever wrong) I intended the point AboutToCauseTrouble[0] and delete everything, but not that I would need to (somehow) set it back to its original position and maybe THEN do it.

I wondered why I NEEDED the copies, and now it makes more sense. Thanks!
I'm putting this in another message because it's worth noting that's the CORRECT code. THAT code works. However, anywhere I used the original (AKA everything _copy) I had problems.

You keep showing us code that works and not the code that's broken. It's a little like going to the auto mechanic with a working car and asking what's wrong with the car in your driveway. You have to post all the code for us to help. Preferably in a program that will compile.

Returning to your code, can you use the cstring functions? The code is a lot easier if you can:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <cstring>

char *
devowel(const char *orig)
{
    //Get count, copy orig, reset copy
    size_t count { strlen(orig)};

    //Allocated to count + 1, copy that
    char *removed { new char[count + 1] };
    char *removed_copy {removed};

    //Vowels array, point to it
    char vowels[] {"AaEeIiOoUu"};

    //Test orig against vowels
    while (*orig) {
        if (!strchr(vowels, *orig)) {
            *removed_copy++ = *orig;
        }
        ++orig;
    }
    *removed_copy++ = 0;

    //Resize
    char *resized{new char[strlen(removed) + 1]};
    strcpy(resized, removed);
    delete[]removed;                             //Here is the problem
    return resized;
}

int
main()
{
    char unvowel[]
    {
    "Just a string that needs unvoweling"};
    char *diditwork
    {
    devowel(unvowel)};
    std::cout << diditwork;
}


Topic archived. No new replies allowed.