sprintf behaveing strangely
Results 1 to 7 of 7

Thread: sprintf behaveing strangely

  1. #1
    Senior Member
    Join Date
    Feb 2003
    Posts
    282

    sprintf behaveing strangely

    Getting strange sprintf results and hopeing someone here can help. The optional argument is somehow being writen to.

    By definition sprintf is suposed to take the format string, optional data, and write it into the output buffer.

    sprintf(outbuf, formatstring, opt1, opt2...);

    This is for an uninstaller, after the program uninstals the uninstaller deletes itself. Not a lame virus.

    So say:

    char ThisFile[] = "C:\Program Files\Blah\file.exe";

    I want a sequence of formated strings:

    char TempString[2][500]; // array of strings

    sprintf(TempString[1], "del \"%s\"\r\n", ThisFile);

    TempString[1] is as expectd, and ThisFile still equals the same

    Now another sprintf:

    sprintf(TempString[2], "if exist \"%s\" goto TryAgain\r\n", ThisFile);

    This is now my problem, it apers both TempString[2] and ThisFile were writen to

    TempString[2] == ThisFile =

    if exist "" then goto TryAgain

    How can ThisFile be writen to, the optional arguments are to be left along corect?

  2. #2
    Jaded Network Admin nebulus200's Avatar
    Join Date
    Jun 2002
    Posts
    1,356
    char ThisFile[] = "C:\Program Files\Blah\file.exe";
    char *ThisFile = "blah";

    char TempString[2][500]; // array of strings
    This bothers me that you hardcoded both...think you are asking for major problems there...It has been unfortunatley too long ago for me to give you reliable advice about this, but something like:

    char **TempString;
    or
    char *TempString[2];

    should work...play with it...

    Arrays in C start with 0 not with 1...you are probably exceeding the bounds on the array...


    Try fixing your indexes, if that doesn't work you are hosing a pointer somewhere....

    /nebulus
    There is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect...There is no escape from it, we are forever slaves to it. Our only hope, our only peace is to understand it, to understand the 'why'. 'Why' is what separates us from them, you from me. 'Why' is the only real social power, without it you are powerless.

    (Merovingian - Matrix Reloaded)

  3. #3
    Senior Member
    Join Date
    Feb 2003
    Posts
    282
    I wrote everything hardcoded for simplicty, the actual code uses functions to retrieve the proper path.

    You found my error, the index, I ment to declair as 3 element array. I actualy cut out the line above where I did assign TempString[0], for simplicity as I knew that line wasnt causeing the problem.

    somtimes I get into a narrow vision when im debuging, that I overlook the obvious

    char TempString[3][500];

    fixed it, thanks so much for your help.

  4. #4
    Jaded Network Admin nebulus200's Avatar
    Join Date
    Jun 2002
    Posts
    1,356
    I wrote everything hardcoded for simplicty, the actual code uses functions to retrieve the proper path.
    You should be very very very careful any time you hardcode the size of arrays like that. Otherwise you are leaving yourself wide open to buffer overflows...which is why I mentioned it. I can look it up and basically explain how to use the double pointer if you need...

    /nebulus
    There is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect...There is no escape from it, we are forever slaves to it. Our only hope, our only peace is to understand it, to understand the 'why'. 'Why' is what separates us from them, you from me. 'Why' is the only real social power, without it you are powerless.

    (Merovingian - Matrix Reloaded)

  5. #5
    Senior Member
    Join Date
    Feb 2003
    Posts
    282
    double pointers confused me, I eventualy started to understand them but then since returning to C am back to the basics, standard pointers, file handles...

    I did come across an error, memory error while writeing a program, and when looked up determined i had a buffer overflow. I read the article too, but didnt fully understand it. but once I solved my error i kinda forgot about it.

    EDIT: Thanks once again nebulus. You encouraged me to read up on buffer overflows, I found a well writen definition and explanation of buffer overflow http://commons.somewhere.com/buzz/20...er.Overfl.html

    I understand it and will now find ways to dynamicaly alocate my arrays for now on.

  6. #6
    Jaded Network Admin nebulus200's Avatar
    Join Date
    Jun 2002
    Posts
    1,356
    If I had the time and energy I would make it a tutorial, but since I don't and I know I won't, guess you will have to make do from this :/

    Here goes a really rough stab at it (if someone wants to chime in a correct defeciencies in my memory go ahead, god knows there are enough of them). This is meant in a general sense and ignores some things you might have to do with pre-allocating or re-allocating memory (which can also lead to problems, but more on that later).

    Ok...in a simple, perfect world, we could just define a simple fixed length array and all is good.

    a)
    char Myarray[12];

    What are the problems with this? Well lets say you are using Myarray to store input from another user and you do no bounds checking on the input just a blind copy of the input to MyArray...Lets also say that the user is a not so nice guy or maybe just a curious type chap, and for SNG they input a string of 15 characters...
    since you are not doing any bounds checking and just blindly assigning to this fixed width array...you could potentially have problems...
    NOTE: This is far from the only kind of overflow, just one of tons. Also note that there is usually more than one way to skin the cat, you could for example check the size of the input before assigning it or use a function that truncates the input to the size of your variable...but that isn't the point here.

    The point, at least how I have always understood it, is that if you dynamically assign the memory, you run less of a risk of allowing an overflow. So rather than prototype Myarray as a fixed length array, make it a pointer (and you will soon find out there really isn't too much of a difference), like so:

    b)
    char *Myarray;

    If memory serves, when you copy the data into Myarray with assignment of the user input, it notes the address of the pointer and copies the data out there, without worries of an overflow since you did it on the fly.

    Now, back to the original declaration (a). If you were to reference array with no indices, you would get a memory address. Why? What C does when you prototype an array like that is to allocate a block of memory for storing Myarray (If I remember right one char == 2 bytes, should look that up), so it picks a memory address assigns it to Myarray, and then allocates 24 bytes after that, and assuming there were no bad, mischevious, or idiotic people in the world, assign the input within those 24 bytes. This is where the buffer overflow comes in, if the user chose input > 12 characters, it exceeds the 24 bytes allocated to the array and starts overwriting other data, at which point, its anybodies guess what happens, usually nothing
    good. When you provide an index to the array in (a) it just jumps that many bytes into the memory block, using the base address assigned to Myarray as the starting point. So for example, Myarray[3] would start off at the memory address contained in Myarray and then would offset 3 (index) * 2 bytes or 6 bytes and then read 2 (char is 2 bytes).

    Since Myarray really holds a memory address, that is why:

    char *Myarray = "blah";

    still works. Myarray still holds the memory address like it is supposed to, array[i] will still reference whatever offset (it knows this cause you defined it as type char so data type size * indice) you chose. The difference, if I remember right, is it doesn't actually assign the total bytes until Myarray is assigned when you use the pointer versus the fixed length Myarray.


    The same thing essentially happens with a multi-dimensional array, although the pointers can get kind of confusing, and I really don't want to delve too far into it, other than to point out that when you set fixed length arrays of any kind or dimension, you still run the risk of an overflow.

    If memory serves, if you were to :

    char Myarray[2][12];

    You have a block of 48 bytes now, divided off at 24 bytes to reference each row...really its usually just a contiguous block, but dividing it again helps sort it out logically. Regardless, you can still essentially think of it the same way as the first array, except now instead of dealing with just one dimension, you are dealing with two. (If someone wants to delve into pointers referencing pointers, be my guest...I would love to, just really don't have time to brush up on it).

    char **Array;

    It would be, at least for this purpose, safe to just think of it as a way of telling C that it is a multidimensional dynamic array. So if you were to in turn do something like:

    char **Array = ({"string1", "string2});

    it should work...Please note: You might have to play with the brackets...I forget exactly how you assign a literal array, but it should be very very close to that...if not that.


    I hope that helps some, I know some of the info is a little off, but you have to forgive me, I haven't programmed in C/C++ in 6-7 years now and have had my brain lazified by not worrying about this crap in perl

    Oh another thing, be careful if you are reusing the same variables to hold different data. Once the pointer has been assigned data, you may need to assign it a null value and then reallocate memory/address again when assigning new data or you may run into the same problems...And do be careful with the pointers...this is where a large degree of memory leaks come from (not dereferencing the pointers and leaving the memory allocated until program exit).

    Hope it helps and was close to factual...

    /nebulus
    There is only one constant, one universal, it is the only real truth: causality. Action. Reaction. Cause and effect...There is no escape from it, we are forever slaves to it. Our only hope, our only peace is to understand it, to understand the 'why'. 'Why' is what separates us from them, you from me. 'Why' is the only real social power, without it you are powerless.

    (Merovingian - Matrix Reloaded)

  7. #7
    Senior Member
    Join Date
    Feb 2003
    Posts
    282
    Thank you nebulus, thats refreshed my memory and is all comeing together again.

    >>I haven't programmed in C/C++ in 6-7 years now and have had my brain lazified by not worrying about this crap in perl

    Yea I loved perl, I didnt have to wory about variable types, and for a great degree made me lazy, I love loosely typed. Then I merged into php, and now back to C/C++ after a couple of months.

    Diging up the chapeters in my text on pointers. Now doing Win32 programing alot of pointers are used and makeing me stressful.

    Thanks so much, it has clerified things, and I understand how declareing as *array without indexies, alocates acording to size of data assigned. So that user input is always same length of memory and no woryes of extra data overwriteing memory beyond the scope of the memory location/variable.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •