Is This Safe?

1
2
3
4
5
6
7
8
9
10
FooFuncProc(LPSTR lpFile)
{
...

     strcpy_s(szFullPath,MAX_PATH,szPath);
     strcat_s(szFullPath,MAX_PATH,"\\");
     strcat_s(szFullPath,MAX_PATH,szFileName);

     lpFile=szFullPath;
}


Is the last statement safe?

I execute the above code ONLY if the passed paramenter is NULL, but I'm just wondering, since I've not allocated any memory to lpFile is it is safe to do what I've just done.

Another lesson in my basic ignorance of pointers.
Last edited on
The code is incorrect. You are not modifying the caller's copy of the parameter, which I presume was the intent. Also note that you don't specify a return value, which is incorrect unless this is a constructor.

You also don't show how szFullPath is allocated in memory, which is crucial to ultimately answer your question. For now I'll just address the first problem:

1
2
3
4
5
FooFuncProc(LPSTR *ppFile) //See the double "p"?  Pointer to pointer.
{
    ...
    *ppFile = szFullPath;
}


That would be the C-way of doing it. Of course, you could opt for the C++ way:

1
2
3
4
5
FooFuncProc(LPSTR &lpFile)
{
    ...
    lpFile = szFullPath;
}

I wasn't intending to display the whole function, just the concept.

I'm passing lpFile as a LPSTR. I either pass a path & filename to open the file, or I pass a NULL value. Here's the function header --

BOOL MyFooFunc(LPSTR lpFile) {

If I pass a NULL value, I have declared this inside the function --

char szFullPath[MAX_PATH];

So my question is, if I pass a NULL parameter into the function, i.e., pass a NULL to lpFile, which is a LPSTR, is it valid to do this after I have filled the szFullPath string with the information I want --

lpFile=szFullPath;

IOW, is that cool or is it corruptible?

I have tried it and it works, but just because it works on my computer doesn't mean it will work on others.

But if it's a valid statement, that's what I want to know.
Last edited on
So szFullPath is an array in the stack. This means that once out of the function, the memory once used by the array can be overwritten. So the answer is: No, it is not correct to do it like that.
I guess I'm not making myself clear...

BOTH STRINGS are WITHIN THE FUNCTION.

All I want to know is, is assigning a LPSTR to a string with the "=" operator a valid statement???

That is ALL I am trying to find out.

I could just have easily said is this valid --

1
2
3
4
5
6
7
8
BOOL MyFunc(LPSTR lpFile)
{
     char szPath[]="c:\\programming\\myfile.txt";

     lpFile=szPath;

     return 0;
}


ALL I want to know is if assigning lpFile to szPath that way for use WITHIN THE FUNCTION is valid or not.

That is ALL I want to know, or will that end up being corrupted? I don't fully understand pointers, so I just want to know if that is a valid and acceptable way to put what is in szPath into lpFile.

That is ALL I am trying to find out.
Last edited on
Perhaps you could accomplish what you want by passing a pointer to allocated memory - perhaps MAX_PATH bytes, into your function, and then do what you want with it there. That way, when the function exits, your memory will be within the scope of your calling function - which hopefully is good yet. In such a scenario, it might be worthwhile to pass into your function the size of the memory it is working with, so that if you are doing concatenations or whatever, your logic within the function can take care not to go beyond the size passed in as a parameter. If you recall, a lot of ODBC and other Api functionbs work that way. You pass in a pointer to an allocated memory block, plus the size of the block. If something goes wrong in the function, the return value can return a bool or an error code.
Please, could somebody just tell me if the above example is valid or not??? I appreciate the desire to explain everything, but ALL ALL ALL I want to know is if the above is valid, or am I likely to run into trouble with it. That is ALL ALL ALL I want to know.
LOL, ok, if you don't use the pointer outside the function, it is perfectly OK to assign it to the pointer.
So the way I'm doing it, i.e., using the "=" operator is better than trying to use strcpy(), etc?
Yes, it is ok. Just remember this:

char szPath[]="c:\\programming\\myfile.txt";

means that szPath is writeable, but cannot grow in size, so don't think you can store larger strings than the original one.
1
2
3
4
5
6
7
8
BOOL MyFunc(LPSTR lpFile)
{
     char szPath[]="c:\\programming\\myfile.txt";

     lpFile=szPath;

     return 0;
}


There's actually a rule about that exact thing that says something to the effect of...

NEVER RETURN THE ADDRESS OF A TEMPORARY.

The compiler will allocate memory for szPath[] on the stack at the point of the function call. When the function terminates the compiler emmitted code will release/free the memory allocated for szPath - the same stack address you've just received back in your program somewhere and perhaps might use for something. The situation is exactly the same as if you use new/malloc to create something; free it; then go about using the object as if it were still valid.

The funny thing about stuff like this is that for relatively small amounts of memory one can sometimes get away with it without crashes. But its pure luck when you do. For myself, I live in mortal fear of memory corruption, as I've lost serious amounts of time fixing these things.

Also, strcpy doesn't enter the picture, at least if I understand you right. Anyway, you can't do a strcpy to lpFile because, as you state, there are some conditions under which it has no memory behind it.
Ahhhhhh.... That's what I really needed to know, webJose. And thanks for clarifying it freddie1. I think I got it down basically, but...

So memory is allocated to the pointer according to the initial assignment, but if I reset the pointer to NULL and then try to assign a larger string to it -- BOOM!

Is that right?
Last edited on
When you assign the pointer, you have a new way of accessing the same stack-allocated bytes. You can write to them using this new pointer, but you cannot reallocate the stack-allocated bytes in any way. You are stuck with the original number of bytes. You can write shorter strings than the original, but never larger ones or you'll corrupt the stack.

You can set the LPSTR pointer to NULL, yes, and you can even assign a larger string like this:

lpFile = "C:\\Another directory\\Some subdirectory\\Just one more for the sake of it\\some other file.txt";

but once you reassign like this, the pointer has no relation whatsoever to its previous address. Actually with this new assignment, you can no longer write to the address pointed because that address is located inside a read-only data section of your executable/DLL. But if you had another stack-allocated string like this:

char someOtherFile[] = "C:\\Another directory\\Some subdirectory\\Just one more for the sake of it\\some other file.txt";

then the same applies, but to this new stack-allocated set of bytes.

Is this any clearer?
I think it's clearer. What you're saying is that as long as I keep the pointer in the same scope, I can reassign it to larger or smaller strings with the "=" operation, and the compiler will automatically take care of the memory allocation for the size of the string I assign it to, but once I've reassigned it, I no longer have access to the previous assignment, which I would have never thought I would anyway.

My main concern is that if I assign a string to the pointer from within the function as demonstrated above is that the pointer is receiving enough allocated memory so as to not corrupt the stack, which from what I've read here, is the case, i.e., as long as I assign it within the same scope (function) it's okay. For example, if I understand correctly, the following would be okay --

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BOOL MyFunc(LPSTR lpFile)
{
     char szOne[]="my name is lamblion.";
     char szTwo[]="her name is the length of my name plus her name.";

     lpFile=szOne;
     MessageBox(hwnd, lpFile, szAppName, MB_OK);

     lpFile=NULL;
     lpFile=szTwo;

     MessageBox(hwnd, lpFile, szAppName, MB_OK);

    return 0;
}


If I understand correctly, the above should be okay.
Last edited on
The sample function is correct and poses no issues.
Okay, thanks for the help. I definitely have a better understanding of it, but I also realize I need to learn about the stack, the heap, and other things re the computer and its architecture.
Topic archived. No new replies allowed.