|
Ali Tavakol wrote: char * f(void)
{
return "Hello";
}
//in main
char *s = f();
This is safe as you are returning a string literal, but it is preferable that you change the function to say const char* f(void).
Ali Tavakol wrote: strcpy(f(), "All");
This is not, you are not supposed to modify a string literal.
Ali Tavakol wrote: CString s = f();
This is safe.
|
|
|
|
|
I am interested in your reply.
I have modified my post.
please explain how you say it?
|
|
|
|
|
Exactly what would you like to be explained?
edit: noticed the modification
Ali Tavakol wrote: char *s = "All ";
strcat(s, f());
It's best to have a habit of putting const. const char *s = "All ";
Again, this is not safe as you are not supposed to modify a string literal which is pointed to by s.
-- modified at 4:29 Thursday 10th August, 2006
|
|
|
|
|
hfry wrote: This is safe
I don't think we have the same notion of safety .
Sorry, but it is not safe: sure, the pointer still 'points' at the same address but the contents of the strings are not protected anymore (we are out of the scope of the function in which the string was local). You save this address in another pointer but that doesn't change the fact that the memory is still unprotected.
So, later in your program you may find garbage characters in your string and you don't know way. It is like using a string allocated with new after having deleted it.
|
|
|
|
|
String literals are statically allocated, ie. memory is allocated for them when the application is loaded. The string is valid throughout the lifetime of the application. This would of course be different if he was allocating a string on the stack.
|
|
|
|
|
Mmmh... true. After searching a little bit on the net, I found that also. So you are right, this is perfeclty safe (shame on me ).
I thought that strings litteral where handled the same as normal strings.
|
|
|
|
|
<br />
char * f(void)<br />
{<br />
char *s;<br />
return s;<br />
}<br />
now which codes in the first post are safe?
-- modified at 4:34 Thursday 10th August, 2006
|
|
|
|
|
const char* f(void)
{
const char *s = "Hello";
return s;
}
This is safe but it is best to write it like this, this way the compiler will definately complain if you try to do something wrong.
You just have to remember that a string literal exists for the lifetime of the application, and that you should not modify the string literal.
edit: i noticed you modified your post...
Ali Tavakol wrote: char * f(void)
{
char *s;
//assume that string s is given by the user
return s;
}
Given by the user? Assuming something like this...
char * f(void)
{
char *s;
char buffer[100];
getuserinput(buffer, 100);
s = buffer;
return s;
}
Then no. You are not supposed to return a pointer to a variable allocated on the stack out of a function.
-- modified at 4:37 Thursday 10th August, 2006
|
|
|
|
|
I think
char * f(void)
{
return "Hello";
}
is almost equivalent to
char * f(void)
{
static char t[] = "Hello";
return t;
}
therefore it is safe to return a pointer to this kind of "temporary" string.
|
|
|
|
|
Cedric Moonen wrote: Sorry, but it is not safe: sure, the pointer still 'points' at the same address but the contents of the strings are not protected anymore
Since his function was returning a string literal, it is safe. String literals are stored in static memory, so the pointer he returns will be pointing to a location in memory that will ALWAYS have that string (at least as long as that program is running).
Granted, this is not a desirable way to return such data, but it is both legal and safe.
Cedric Moonen wrote: So, later in your program you may find garbage characters in your string and you don't know way. It is like using a string allocated with new after having deleted it.
That would have been the case if the code he wrote was changed to:
char* f()
{
char buffer[20] = {0};
strcpy(buffer, "Hello");
return buffer;
}
But since he was returning a string literal, it is not the case.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Odd - I have no idea why your post was voted down, it was completely correct.
Peace!
-=- James If you think it costs a lot to do it right, just wait until you find out how much it costs to do it wrong! Avoid driving a vehicle taller than you and remember that Professional Driver on Closed Course does not mean your Dumb Ass on a Public Road! DeleteFXPFiles & CheckFavorites (Please rate this post!)
|
|
|
|
|
Hi!!
I am newbie in VC++. I was facing the problem while executing application(.exe) build using VC8. The application was ported from VC6 to VC8. The problem I was the error:
MSVCR80.dll was not found. Re-installing the app........
I gone through many articles and found this is a rather common problem. I checked my application manifest file which was correct and refering to new MFC 8. Also checked .exe which has manifest file embeded under RT_Manifest with id 1. So nothing seems to be wrong still i was not able to run .exe. When I checked with DEPENDACY WALKER it was showing same error that he couldnt found msvcr80.dll.
After that I changed setting for linker to ignore library MSVCRT.LIb. And now the problem is no more. When I checked .EXE with Dependency Walker, I was getting MSCVR80D.dll for debug build. Also my application is able to run now.
Is it right thing whatever I have done?? Is ignoring library MSVCRT.LIb is a right option. I hope it wont create problems in future.
Thx !!!!
|
|
|
|
|
|
I Dont know whether solution I have found is right or wrong!!
Thx.
|
|
|
|
|
Try running your application in a system which does not have Visual Studio installed. (If needed the system may have .NET framework though.) If it runs well once, it will run again anywhere, provided you also distribute the dependent DLLs with your application.
Abhishek
|
|
|
|
|
Hi Abhishek!!
Unfortunately I dont have another machine without VC2005 installed. But when I checked, I foucnd that these files are getting loaded through following location.
D:\windows\winsxs\x86_microsoft.vc80.debugcrt_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c
And this is perfect as per the manifest file says. so I guess there is no problem.
One more doubt!! What does it mean when we say ignore library! And why my application links to msvcr80d.dll even if when I ignored MSVCRT.
Thx for the help!!
|
|
|
|
|
sach!! wrote: One more doubt!! What does it mean when we say ignore library! And why my application links to msvcr80d.dll even if when I ignored MSVCRT.
to direct the linker to ignore default library references in all .obj files.
-- modified at 5:54 Thursday 10th August, 2006
never say die
|
|
|
|
|
Thx sunit!!
That means My application wont link to default MSVCRT.lib(VER:6 for VC6). And thats why its linking to new Ver:8 according to manifest file.
But again that leaves the question that why are those policies needed in WinSxS folder. Those policies are clearly indicating that any reference to old ver should redirect to the New version.
Seems some problem with policies!
Thx
|
|
|
|
|
Ok, I think I should answer your question in detail.
Now, when you said you are migrating a project from VC6 to VC8, I am assuming that you have just opened the existing VC6 project file in VC8. So the linker directories were retained in the new project which was opened in VC8. This will happen if the programmer who had originally created the project had explicitly linked to MSVCRT.LIB (which is actually the c-runtime library). So the VC8 compiler was trying to link to that LIB as well! And since .lib files are not compiler independent, you got an error. I am not sure if you unlinked the older version 6 library! Please let me know.
Secondly, if the programmer had not, linked to the MSVCRT.lib explicitly, then the compiler will not look for version 6 of MSVCRT. Instead it will look for the current version i.e. version 8 of MSVCRT.lib. By the way, lining to MSVCRT.lib requires you to distribute MSVCRT80.dll with the application. Take a look at this for further details: http://msdn2.microsoft.com/en-us/library/abx4dbyh.aspx
Since, it was not present in the application directory, the error was found.
However all this is my own conjecture. I suggest it would be better if you post the buildlog.htm (that is generated in the debug folder) here in this forum so I can take a closer look.
Abhishek
|
|
|
|
|
Hi abhishek!!
Thx for the reply!
I understood what u r trying to say. I checked my project and other dependent projects too. I found that some of my projects were linking to MSVCRT, but besides that its a correct version i.e 8 of MSVCRT is getting loaded. This I checked using DEpendancy Walker.
This is what I done while converting projects from VC6 to VC8. I copied full folders, made back-up and then used new copy. So I think its not the case 1 as u told.
>lining to MSVCRT.lib requires you to distribute MSVCRT80.dll with the application
I am not sure about this one. But I think that is why there is a manifest file. When i gone through some articles I found that manifest files are responsible for getting these dlls. Also manifest files are embeded into the appilcation(.exe). I also checked that and it was found in my .exe.
Althogh my problem has been solved using Debug build. I just want to confirm that my release build also work fine.
Thx again!!
|
|
|
|
|
sach!! wrote: I just want to confirm that my release build also work fine.
The best way would be to run it on a system which does not have VS installed.
This will confirm things once and for all.
Abhishek
The worst loneliness is not to be comfortable with yourself.
--Mark Twain
|
|
|
|
|
hello all,
how can i make, a forward declaration class's enum member, being
visible by another class?
consider the following case,
----------------------------
dog.h
----------------------------
#ifndef DOG_H
#define DOG_H
// class forward declaration.
class cat;
class dog
{
public:
enum dog_enum
{
d0, d1, d2
};
void speak(cat *c);
};
#endif
----------------------------
cat.h
----------------------------
#ifndef CAT_H
#define CAT_H
#include "dog.h"
class cat
{
public:
void speak(dog *d, dog::dog_enum e);
};
#endif
The above cat and dog just work fine. Now, let me create an enum type
for cat too.
----------------------------
dog.h
----------------------------
#ifndef DOG_H
#define DOG_H
// class forward declaration.
class cat;
class dog
{
public:
enum dog_enum
{
d0, d1, d2
};
// OPPS! HOW DO WE FORWARD DECLARE ENUM???
void speak(cat *c, cat::cat_enum e);
};
#endif
----------------------------
cat.h
----------------------------
#ifndef CAT_H
#define CAT_H
#include "dog.h"
class cat
{
public:
enum cat_enum
{
c0, c1, c2
};
void speak(dog *d, dog::dog_enum e);
};
#endif
My question is, how can "dog" see the cat_enum, which is re-inside cat?
I was understand that forward declaration for enum is not allowed in
c++.
Is there any workaround for this?
Thank you very much
|
|
|
|
|
I'm a noobie of visual c++ and currently using vc++ express 2005.
I'm creating an application to handle data from a device connected both
on a serial port and via tcp/ip networking and been successful with the work so far.
My problem is within the application interface.
I have a mdichild which will show data send from the device within the serial port and then
do some decoding and throw it as keystokes.
Within the mdichild I put a button which when it clicked it will send the data into another
mdichild form ( which will process the data, querying, bla.. bla..bla...)
How can I acomplish this ?
Thanks
|
|
|
|
|
Hi..error in reading...
void ReadModelDetail()
{
char FileBuffer[25] = {0}, TempString[15] ={0};
char cTagLength[5];
char tModelName[25]={0},tDesc[60]={0};
int Count=0,iCount=0;
CModelInfo *info;
if(!OpenReadModel())
{
return;
}
OModelList.RemoveAll();
memset(TempString,0,15);
memset(FileBuffer,0,20);
MdlFile.Read( FileBuffer, DEF_HEADERSIZE );//It reads "Esim"
MdlFile.Read( TempString,sizeof(int)); //it reads "6"
Count = atoi(TempString);
for(iCount=0; iCount< Count; iCount++)
{
memset(tModelName,0,25);
MdlFile.Read(tModelName,25); //It should read "PPS01" but it read "S01"
}
CloseReadModel();
}
The file looks like this ESIM 6 PPS01..
The Model name is PPS01..but it reads like tht it neglect first 2 characters in the name and read only "S01" if the model name is DT002 then it reads on ly "002"..
What can i do?
Anu
|
|
|
|
|
The problem is here:
Anu_Bala wrote: MdlFile.Read( TempString,sizeof(int)); //it reads "6"
That is false. sizeof(int) returns 4, so you read 4 characters ! You have to make a difference between the size of an integer (always 4 bytes) and the size of the string that represents this character (can vary depending of the number of digits).
If your integer is always smaller than 10, then you can read only one char. But if you don't know how many digits it will contain, then you are in trouble. It is better to store the complete line in a buffer and then scan it for white spaces inside it (like I suggested yesterday). Or use scanf as somebody suggested you also.
|
|
|
|