views:

1182

answers:

8

Hi all..

I'm currently working on a project that depends on me providing a path to a file (eg. "C:\Path.pth"). Now, I had everything working yesterday by calling my std::string with:

std::string path("C:\\Path.pth");

-- But now it doesn't work!? It throws a bad_alloc. Seems like the '\' character is the problem. I even tried using \x5C as the ascii-value of it instead, but same result.

Now, my question is, is it possible that I have screwed up some #define, some compiler-option or something else "non-code" that could've caused this? I'm using VS 2005, btw ..

Any help would be much appriciated.. Ty..

[EDIT] Fixed the back-slashes in my question. Ty for the comments, still need an answer though :(

A: 

Define the string as: "C:\\Path.pth"

Danny Whitt
A: 

No, you didn't have it "working" yesterday either. '\' needs to be escaped like so:

std::string path("c:\\path.pth");

You probably did a forward slash yesterday, which can work in this situation as well.

std::string path("c:/path.pth");
A: 

Hehe, seems like stackoverflow.com does wierd things to my double-slashes :P

I did double-back-slash yesterday in my code.. Dunno why these forums change it in this post

Meeh
looks like markdown uses \ as an escape char as well, usng four backslashes or using a code block (indent the line by 4 spaces iirc) will work, might want to edit your question so it shows up correctly.
TFKyle
I guess I'm just a prude but please use professional language.
Onorio Catenacci
Sorry about that .. Edited..
Meeh
A: 

Assuming your double-backslash is correct, I'd guess you're running on Vista?

Vista won't let your write into the root directory of the C drive by default. Try one of the following:

  • Turn off UAC, or
  • Run your application as "Administrator", or
  • Write into a subdirectory.
Roddy
The error is during string allocation, not file access !
PierreBdR
+5  A: 

As your error suggest, the problem is due to memory allocation (i.e. the bad_alloc exception).

So either you have no more memory (unlikely) or you have a buffer overrun somewhere before (quite likely in my opinion) or some other memory issues like double free.

In short, you do something that messes up the memory management layout (i.e. all these information in between allocated blocks). Check on what happens before this call.

PierreBdR
A: 

PierreBdR

.. That sounds very likely. Or at least, it have to :P

Since no one have mentioned some kind of /SetStringCharSize:2bit-compiler option, I think it's safe to assume that my code has to mess something up, somewhere, and that it's not just a silly compiler-option (or similar) that's wrong..

Meeh
+2  A: 

Just want to let you all people know that the bug has been found and fixed. Seems like TinyXML was bugged when using with the TIXML_USE_STL-definition done, so for some reason the constructor to the TiDocument did mess my memory-layout up, so badly that the next std::string I defined has to throw a bad_alloc exception - and luckily for me, exactly on the 4th char of the string, which in my situation was '\', resulting in a (for me) rather subtle error.

Thx for the help everyone..

Meeh
Glad you found the problem. But, I don't understand what you meant by "throw a bad_alloc exception ... exactly on the 4th char of the string". That makes no sense to me.
Michael Burr
I agree.. Doesnt make sense to me either. Actually I think I was a bit vargue in that point :)If I did a std::string path = "C:\\Test.xml", a bad_alloc would be thrown.If I did a path = "C:Test.xml", no bad_alloc would be thrown. So don't ask my why it did what it did :P
Meeh
+1  A: 

Don't forget, you should use forward slashes in paths, even on windows:

[15.16] Why can't I open a file in a different directory such as "..\test.dat"?

Because "\t" is a tab character.

You should use forward slashes in your filenames, even on operating systems that use backslashes (DOS, Windows, OS/2, etc.). For example:

#include <iostream>
#include <fstream>

int main()
{
  #if 1
    std::ifstream file("../test.dat");  // RIGHT!
  #else
    std::ifstream file("..\test.dat");  // WRONG!
  #endif

  ...
}

Remember, the backslash ("\") is used in string literals to create special characters: "\n" is a newline, "\b" is a backspace, and "\t" is a tab, "\a" is an "alert", "\v" is a vertical-tab, etc. Therefore the file name "\version\next\alpha\beta\test.dat" is interpreted as a bunch of very funny characters. To be safe, use "/version/next/alpha/beta/test.dat" instead, even on systems that use a "\" as the directory separator. This is because the library routines on these operating systems handle "/" and "\" interchangeably.

Of course you could use "\\version\\next\\alpha\\beta\\test.dat", but that might hurt you (there's a non-zero chance you'll forget one of the "\"s, a rather subtle bug since most people don't notice it) and it can't help you (there's no benefit for using "\" over "/"). Besides "/" is more portable since it works on all flavors of Unix, Plan 9, Inferno, all Windows, OS/2, etc., but "\" works only on a subset of that list. So "\" costs you something and gains you nothing: use "/" instead.

(From C++ FAQ Lite)

Jon