weird random values

hi guys!
what could cause a non-randomized algorithm to return different values
for the same input each time it's called?
i'm using strtoul() in my code,in a manner i think is similar to
1
2
3
4
5
6
double somefunction(char* str)
{
char* p;
double x=strtoul(str,&p,10);
return x;
}


now if i call this function with for example str="123" say N times,
most often the returned value will be 123,as expected,but sometimes(rarely though) i get 1234.then if i rerun the program,i get 1235,if i rerun it again,i get 1236.the 4th digit is incremented until it reaches 9,then everything goes back to normal for another twenty,bugfree calls.
could anyone plz tell me why that happens?thx.



From http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/

endptr
Reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value.
This parameter can also be a null pointer, in which case it is not used.

Since you're not using this pointer, you just pass in NULL. You're passing in an uninitialized pointer which would cause undefined behaviour, such as the behaviour you're experiencing, when the pointer is accessed.
i just tried that,it doesn't fix the problem...
Can we see the new code, perhaps including the caller? Did you try this?

1
2
3
4
double somefunction(char* str)
{
    return strtoul(str, NULL, 10);
}
here's the code:
and thx a lot for ur help!
u'll notice i've followed ur advice:)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//explanations after the code


void Assign(int q,int r,char* str,Node** N,int& I)
{
static NumNode* C=new NumNode[MAX];
static int k=0;

if((r-q)>1)
{
    char *sss=new char[r-q-1];
    for(int i=q+1;i<r;i++)
    sss[i-(q+1)]=str[i];

    double x=strtoul(sss,NULL,10);

    NumNode nun(x);
    C[k]=nun;


    N[I]=&C[k];k++;
    I++;


}

}




so about the code:
Assign(int q,int r,char*str,Node**,int &i)
q and r are indices refering to characters in the string,
N is an array of pointers to objects from a class called Node,
i just stores the lenght of N.
two classes inherit from Node,called NumNode and OpNode.
for example:
Assign(1,4,str,N,i) where str="1+23-4"
will parse the string from str[1+1] to str[4-1]
in search of an integer value,then store it in a NumNode,wich is
a class derived from a base class called Node.

now as i said before it works fine most of the time,but if i run it multiple times in a row,
it'll return nonsense once or twice before working properly again.


thx a lot for ur help and patience.




A few things:
(1) There's a memory leak, you should delete[] sss; when you're done with it.
(2) How big is MAX? Because k is never set back to zero. This will cause an array index out of bounds when k >= MAX.
(3) I'm suspicious of the loop which assigns the chars to sss. If i - (q+1) is never zero, then you're going to have leading uninitialized chars. I would initialize all of sss to be zero first, like so:
char *sss=new char[r-q-1](); (the brackets cause zero initialization). I would also try printing sss after the loop to see what's in there.
(1) ur right about using delete,thx!
(2) MAX is 260,and in practice i don't expect strings longer than 30 or so.
(3) i think the loop works correctly,because as you see i starts on i=q+1:
1
2
for(int i=q+1;i<r;i++)
    sss[i-(q+1)]=str[i];

that means sss[0]=str[q+1],sss[1]=str[q+2] and so on...so there's no problem here.

a little question though...what happens when i don't delete sss?
i thought that the pointer sss was simply destroyed when the function returned,and that the memory
it refered to would become available again,but filled with garbage values...
thx again,i'll also try printing the values...
change char* p; to char* p = NULL; see if that helps
ok...so i added a line to print sss:
1
2
3
4
5
char *sss=new char[r-q-1];
for(int i=q+1;i<r;i++)
    sss[i-(q+1)]=str[i];

cout<<sss;

now as i said in my previous post,the loop seems to properly assign values to sss[0],sss[1],...,sss[r-q-1];
but after cout<<sss; the printed string is longer than r-q-1
(i find it strange since char *sss=new [r-q-1]; )
for example when r-q-1==1 and i expect the single element of str to be str[0]==2;the printed version
of sss will be something like 2#^ or 2(other ASCII characters) and of course sometimes strings like 2$5
wich then make strtoul return 25 instead of the expected value 2.
so...i really don't have any idea what's happening here...plz help!
and thx a lot for helping me narrow it down...
Try zero-initializing sss:

char *sss=new char[r-q-1](); (note the () brackets at the end)

You might also need to make the size of sss to be r-q (i.e. you may need to have space for the null terminating character).

what happens when i don't delete sss?
i thought that the pointer sss was simply destroyed when the function returned,and that the memory it refered to would become available again

Well, it's a leak. When you do char* sss = new char... in one function call, and let's say sss contains the memory location 0xABCDEFFF, if you don't delete[] it, that memory location won't have its contents freed until the program is terminated. You can go back in the function and get a new memory location for sss, but this function doesn't clean up after itself so the process will just use more and more memory. You probably won't notice it for a program of this size, but it's something to keep in mind.
Last edited on
i tried that!but as i said,the for loop replaces all zeros with new values(from sss[0] to sss[r-q-1])
as i said in my previous post,cout<<sss prints strings longer than r-q-1.i'm repeating myself,so please just
check my last post^^
thx for the explanation about the leak,i'll keep it in mind.and ceruleus,i've already fixed that with no improvements,but thx.
Last edited on
I just edited my post as you responded. It looks like you need to make the size of sss bigger by one, and place the null terminator at the end.

i.e.

1
2
3
char* sss = new char[r-q]();
...
sss[r - q - 1] = '\0';
Last edited on
Wow thx a million times!that solved the problem!i love u shacktar:D
Topic archived. No new replies allowed.