Valhalla Legends Forums Archive | C/C++ Programming | String Pointer Causing Access Violation

AuthorMessageTime
Dyndrilliac
[code]#include <string.h>

class String {
  public:
    String(char *strText);
    void fSetString(char *strText);
    char *fGetText();
    int fGetLen();
    bool fCompareTo(char *strText);
  private:
    char *szText;
    int iLength;
};

String::String(char *strText) {
    szText = strText;
    iLength = strlen(strText);
}

void String::fSetString(char *strText) {
    szText = strText;
    iLength = strlen(strText);
}

char *String::fGetText() {
    return szText;
}

int String::fGetLen() {
    return iLength;
}

bool String::fCompareTo(char *strText) {
    if (strcmp(szText,strText) == (0)) {
        return true;
    } else {
        return false;
    }
}[/code]

When I call fSetString() after creating a valid instance of the class I get an Access Violation error. It appears to happen because I am altering the string pointer "szText". I wrote a small Test App:[code]#include <stdio.h>
#include "StringClass.h"

int main()
{
    String sz_A_Name("Matt");
    char *sz_B_Name = "Matt";
    char *sz_C_Name = "John";
    char *szTemp = "";
   
    if (sz_A_Name.fCompareTo(sz_B_Name) == true) {
        printf("\"%s\" and \"%s\" are the same!\n", sz_A_Name.fGetText(), sz_B_Name);
    } else {
        printf("\aHouston. we have a problem!\n");
    }

    if (sz_A_Name.fCompareTo(sz_C_Name) == false) {
        printf("\"%s\" and \"%s\" are not the same!\n", sz_A_Name.fGetText(), sz_C_Name);
    } else {
        printf("\aHouston. we have a problem!\n");
    }

    printf("The name \"%s\" is %i characters long!\n", sz_A_Name.fGetText(), sz_A_Name.fGetLen());
    printf("Please enter a new name: ");
    scanf("%s", szTemp);
    sz_A_Name.fSetString(szTemp);
    printf("Your new name is: %s\n\n", sz_A_Name.fGetText());
    printf("Test completed successfully!\n\n");

    return 0;
}[/code]

The program crashes when inputting the new name for the string. I tried debugging it and as earlier mentioned, discovered it was an Access Violation. I think szText is being invalidated after calling the constructor because the data it is pointing to is allocated on the heap, whereas the data being passed to it is allocated on the stack. Is there anyway to force where the data being passed to the constructor is allocated, or can anyone suggest a good way to get around this?
June 10, 2005, 4:51 PM
OnlyMeat
The stl aready provides a string class, why re-invent the wheel? Apart from that your code is incredibly ugly.

[code]
#include <string>
#include <iostream>

using namespace std;

int main()
{
  string MyStringClass = "hello world";
  if ( MyStringClass == "hello world" )
        cout << "std::string's overloaded equality operator returned true" << endl;
     
  return 0;
}

[/code]
June 10, 2005, 6:18 PM
Arta
You're not allocating any memory to szTemp. You're creating a pointer to an empty string:

[code]
char *szTemp = "";
[/code]

You need to allocate some memory, either on the stack:

[code]
char szTemp[255] = {0};
[/code]

or on the heap:

[code]
char *szTemp = new char[255];
[/code]

You should also bare in mind that your class doesn't do allocate any memory for the string - it just saves a pointer to the memory allocated by the caller of fSetString. This means that, for the duration of the use of your string class, the memory must remain valid. This will break:

[code]

void somefunction(String *str)
{
  char x[] = "123";
  str->fSetString(x);
 
  return;
}

int main(int, char**)
{
  String *str = new String();

  somefunction(str);
 
  // the string is now invalid - because x was declared in the scope of somefunction
}
[/code]

To make it more robust, have your constructor call fSetString, and have fSetString allocate some memory into which you should copy strText. Make sure you free it in your (missing!) destructor.
June 10, 2005, 6:44 PM
Dyndrilliac
Thanks Arta, fixed :)[quote]"Matt" and "Matt" are the same!
"Matt" and "John" are not the same!
The name "Matt" is 4 characters long!
Please enter a new name: Joe
Your new name is: Joe
Please enter another new name: Dave
Your new name is: Dave

Test completed successfully!

Press any key to continue[/quote]
June 10, 2005, 8:46 PM
OnlyMeat
[quote author=Arta[vL] link=topic=11793.msg115371#msg115371 date=1118429043]
You're not allocating any memory to szTemp. You're creating a pointer to an empty string:

[code]
char *szTemp = "";
[/code]

You need to allocate some memory, either on the stack:

[code]
char szTemp[255] = {0};
[/code]

or on the heap:

[code]
char *szTemp = new char[255];
[/code]
[/quote]

That is incorrect, using this notation allocates memory on the stack:-

[code]
char* buf = "";
char* buf2="hello";
cout << sizeof(*buf) << buf2 << endl;
[/code]

For buf it allocates a zero length string with a terminator on the stack, and for buf2 it allocates 5 bytes for the string and a null terminator on the stack.


June 10, 2005, 8:57 PM
Arta
I am not incorrect. Go away. The examples you provide are also ways to allocate memory on the stack, they are not the only ways. As a matter of fact, they are worse ways: the example you provide is not safe if you intend to write to the string.

This is the second time you've incorrectly told me I'm wrong. A somewhat essential prerequisite for being a smartass know-it-all is to actually know what you're talking about.
June 10, 2005, 11:11 PM
OnlyMeat
[quote author=Arta[vL] link=topic=11793.msg115391#msg115391 date=1118445100]
I am not incorrect. Go away.
[/quote]

Ok, lets clarify this shall we.

[quote author=Arta[vL] link=topic=11793.msg115371#msg115371 date=1118429043]
You're not allocating any memory to szTemp. You're creating a pointer to an empty string:

[code]
char *szTemp = "";
[/code]
[/quote]

Seems clear to me you are saying the code snippet above doesn't allocate any memory. This is incorrect, if you don't believe me run the code in my reply, you will find the size of the variable buf == 1 (the null terminator). This is clearly allocating 1 byte on the stack giving you a valid zero length string:-

[code]
char* buf = "";
char* buf2="hello";
cout << sizeof(*buf) << buf2 << endl;
[/code]

I didn't think this forum was in the habit of pedaling false information. Am i wrong?.

[quote author=Arta[vL] link=topic=11793.msg115391#msg115391 date=1118445100]
This is the second time you've incorrectly told me I'm wrong. A somewhat essential prerequisite for being a smartass know-it-all is to actually know what you're talking about.
[/quote]

If someone relays incorrect information then i will attempt to correct it. If you don't like it, then i have a simple solution, don't post it in the first place. Bitching at someone simply because they correct your mistakes demonstrates weak character.

I'm certainly not a know-it-all and would never presume to be. I don't believe anyone person knows everything. We all need to be corrected at one time or another, im just trying to help you.
June 11, 2005, 1:48 AM
Arta
[quote]
That is incorrect, using this notation allocates memory on the stack:-
[/quote]

You didn't even mention that you were referring to the amount of memory allocated. You just said "That is incorrect".

Sure, an empty string consumes a byte for the null terminator. What's that got to do with anything? I was trying to express that he's not allocating any memory for his temporary string, which he isn't, and that that was the cause of his problem, which it was. Then I showed him how to do it.

You can hardly expect people not to get irritated if you nit-pick at minutia.
June 11, 2005, 1:57 AM
Kp
[quote author=OnlyMeat link=topic=11793.msg115401#msg115401 date=1118454495]This is incorrect, if you don't believe me run the code in my reply, you will find the size of the variable buf == 1 (the null terminator). This is clearly allocating 1 byte on the stack giving you a valid zero length string:-[code]char* buf = "";
char* buf2="hello";
cout << sizeof(*buf) << buf2 << endl;
[/code][/quote]

Too bad this is also incorrect. :)  In most modern compilers, string constants can (and should!) be allocated read-only, which means the null terminator is going into a .rdata section, not on the stack.  Given that, you're consuming 4 bytes on the stack for the pointer to the null (ok, 8 bytes if it's a 64bit architecture).  buf2 also consumes a word's worth of space on the stack, defering the actual string content to .rdata.  Of course, given that you still use a C++ front-end that has to translate to C code first, it's understandable your remarks are a bit outdated (such as believing that string constants are put in writable memory).  Finally, using sizeof(*buf) there is a bit silly if you're trying to prove how much space buf consumes.  buf consumes 1 word for the pointer, and 1 byte for the null terminator.  sizeof(*buf) is equivalent to sizeof(char), since *buf is a char.  sizeof(char) is 1 on every system I've ever seen, so it doesn't matter what you point buf at - you'll still get 1 for that sizeof.
June 11, 2005, 3:00 AM
OnlyMeat
[quote author=Kp link=topic=11793.msg115410#msg115410 date=1118458813]
Too bad this is also incorrect.
[/quote]

Say what you like but the point is buf points to 1 byte of memory. You just agreed with that thanks :).
June 11, 2005, 4:24 AM
Dyndrilliac
[quote author=OnlyMeat link=topic=11793.msg115415#msg115415 date=1118463847]
[quote author=Kp link=topic=11793.msg115410#msg115410 date=1118458813]
Too bad this is also incorrect.
[/quote]

Say what you like but the point is buf points to 1 byte of memory. You just agreed with that thanks :).
[/quote]

Didn't you read what he said? Buf uses 5 bytes, not 1. 4 for the pointer itself, and 1 for the actual data. Also, it isn't on the stack.
June 11, 2005, 5:01 AM
OnlyMeat
[quote author=Dyndrilliac link=topic=11793.msg115416#msg115416 date=1118466104]
Didn't you read what he said? Buf uses 5 bytes, not 1. 4 for the pointer itself, and 1 for the actual data. Also, it isn't on the stack.
[/quote]

Do you even know what a pointer is? clearly you don't. A pointer, points to a location in memory. buf is defined as a pointer to a zero length string with a null terminator. Therefore the size of the data it points to is 1 byte.

It seems you can't read or program because you obviously could not understand my previous post to reply in such a way. Here is it again for you:-

[quote author=OnlyMeat link=topic=11793.msg115415#msg115415 date=1118463847]
Say what you like but the point is buf points to 1 byte of memory. You just agreed with that thanks :).
[/quote]

Kp is correct that the location is not on the stack. It has a static lifetime, however it must still be allocated and loaded into memory at runtime. Which proves the point that the variable buf will point to 1 byte of data. It doesn't matter if it's on the stack or allocated when the program starts statically it will be allocated in memory.
June 11, 2005, 6:15 AM
Dyndrilliac
[quote author=OnlyMeat link=topic=11793.msg115379#msg115379 date=1118437048]That is incorrect, [b]using this notation allocates memory on the stack:-[/b[/quote]

You're still incorrect in either case. And yes, I am aware of what a pointer is. When you said point to I took that to mean, the program itself refers to it (*buf) as 1 byte, which is not the case.
June 11, 2005, 7:07 AM
OnlyMeat
[quote author=Dyndrilliac link=topic=11793.msg115423#msg115423 date=1118473648]
You're still incorrect in either case. And yes, I am aware of what a pointer is. When you said point to I took that to mean, the program itself refers to it (*buf) as 1 byte, which is not the case.
[/quote]

You still don't understand do you?
The point is it allocates memory for that null terminated string, it doesn't matter if it's allocated on the stack heap/free store or statically when the program starts, it's still allocated.

Arta originally said no allocation occurs, and my point stands that this is not true. If you don't understand the posts don't bother replying as you simply embarrass yourself by making dumb remarks.

June 11, 2005, 8:16 AM
Dyndrilliac
[quote author=OnlyMeat link=topic=11793.msg115427#msg115427 date=1118477789]
[quote author=Dyndrilliac link=topic=11793.msg115423#msg115423 date=1118473648]
You're still incorrect in either case. And yes, I am aware of what a pointer is. When you said point to I took that to mean, the program itself refers to it (*buf) as 1 byte, which is not the case.
[/quote]

You still don't understand do you?
The point is it allocates memory for that null terminated string, it doesn't matter if it's allocated on the stack heap/free store or statically when the program starts, it's still allocated.

Arta originally said no allocation occurs, and my point stands that this is not true. If you don't understand the posts don't bother replying as you simply embarrass yourself by making dumb remarks.


[/quote]

I understand the posts perfectly fine you arrogant pretentious prick. I never said anything regarding Arta's post. I was simply saying that taking away everything else in this thread but YOUR original post, you ALSO posted something that is WRONG. If you have to insult other people with your stubborn fantasy world where noone is correct but you to get over the fact that within the last week you have been WRONG on several occasions then so be it but don't be surprised when more people get sick of seeing your crap and you find yourself banned.

Your problem is you can't politely interject in the conversation - everyone already in it has got to either be wrong or ignorant otherwise the the threads of the universe cave in on themselves and existence negates itself.

Edit: Oh, and one one more think I would like to point out. Arta's response was helpful, and is the reason my program works now - yours on the other hand was not. You said nothing helpful whatsoever, which makes me ponder, whats the purpose of you posting in this thread at all?
June 11, 2005, 5:18 PM
Adron
[quote author=OnlyMeat link=topic=11793.msg115427#msg115427 date=1118477789]
[quote author=Dyndrilliac link=topic=11793.msg115423#msg115423 date=1118473648]
You're still incorrect in either case. And yes, I am aware of what a pointer is. When you said point to I took that to mean, the program itself refers to it (*buf) as 1 byte, which is not the case.
[/quote]

You still don't understand do you?
The point is it allocates memory for that null terminated string, it doesn't matter if it's allocated on the stack heap/free store or statically when the program starts, it's still allocated.

Arta originally said no allocation occurs, and my point stands that this is not true. If you don't understand the posts don't bother replying as you simply embarrass yourself by making dumb remarks.
[/quote]

I'll take this time to point out that there is a possibility of no allocation occurring for the string. There will always be an allocation for the pointer (4 bytes in the intel 32-bit architecture), but the empty null terminated string may not necessarily cause any allocation at all to happen. Hint: Look at compiler optimizations for merging string constants.

Additionally for the string, no allocation will happen at run-time, and there will also not be an allocation done on stack, both of which you have incorrectly claimed before.



Edit: Throwing in more examples of how virtually every post by OnlyMeat is incorrect...



[quote author=OnlyMeat link=topic=11793.msg115401#msg115401 date=1118454495]
Seems clear to me you are saying the code snippet above doesn't allocate any memory. This is incorrect, if you don't believe me run the code in my reply, you will find the size of the variable buf == 1 (the null terminator). This is clearly allocating 1 byte on the stack giving you a valid zero length string:-

[code]
char* buf = "";
char* buf2="hello";
cout << sizeof(*buf) << buf2 << endl;
[/code]
[/quote]


#1: It's not allocating a byte on the stack
#2: It may not be allocating anything at all
#3: You're not testing for anything being allocated; example:
[code]
char* buf = 0;
char* buf2="hello";
cout << sizeof(*buf) << buf2 << endl;
[/code]

Tell me how assigning null to a pointer would be allocating a byte for it? Yet according to you, sizeof says it does? ;)



[quote author=OnlyMeat link=topic=11793.msg115415#msg115415 date=1118463847]
Say what you like but the point is buf points to 1 byte of memory. You just agreed with that thanks :).
[/quote]

Memory is committed (in win32) in 4096 byte blocks, also known as pages. Your pointer will point to somewhere in your address space. There most likely won't be just 1 byte available at the location buf points to, much like when you allocate 5 bytes there won't most likely be just 5 bytes where your pointer points to. Maybe what you wanted to say was "buf points to 1 byte of memory allocated for you to use as you like"? Unfortunately that'd be incorrect as well...



[quote author=OnlyMeat link=topic=11793.msg115419#msg115419 date=1118470515]
It has a static lifetime, however it must still be allocated and loaded into memory at runtime. Which proves the point that the variable buf will point to 1 byte of data. It doesn't matter if it's on the stack or allocated when the program starts statically it will be allocated in memory.
[/quote]

There will be memory for the '\0', that's all you can say. That memory may have been allocated for the byte, or it may have been allocated for something else and reused for the '\0'. The memory may be allocated a load-time, or it may have been allocated much earlier. An example would be writing code for a BIOS chip, in which case you might say the memory was allocated when the EEPROM was written. The point is that the declaration char *buf = ""; not necessarily causes an allocation, and particularly doesn't give you  memory that you can do anything other than read a '\0' from.
June 12, 2005, 5:06 PM
St0rm.iD
Aren't all string constants allocated and loaded into memory at startup?
June 19, 2005, 5:38 PM
Adron
[quote author=Banana fanna fo fanna link=topic=11793.msg116526#msg116526 date=1119202720]
Aren't all string constants allocated and loaded into memory at startup?
[/quote]

Not necessarily. They can be memory mapped from an exe file, meaning they load when you access them. Some string constants may have been merged with other string constants, meaning they're not allocated any separate space. In some applications constants aren't loaded at startup, they just exist (example: BIOS ROM).
June 25, 2005, 6:27 PM

Search