views:

163

answers:

7
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <iostream>

using namespace std;


char a[21]; // If this is put inside the function unter -> junk output
char* b="";

void unter()
    {
        char *new_str = "";


        strcpy(a, new_str);

        char str_temp[10]="";
        int chnum =0, neighbor1=3, neighbor2=5, mynode=4;

        sprintf(str_temp,"%d",chnum);

        b = strcat(a, str_temp);
        b = strcat(b, "_from");
        sprintf(str_temp,"%d",mynode);
        b = strcat(b, str_temp);
        b = strcat(b, "to");
        sprintf(str_temp,"%d",neighbor1);
        b = strcat(b, str_temp);


    }

int main()
{
    unter();
    cout << a;
    cout << b;
    std::cin.get();
}

This is my code in C++. I'm not sure how the character array 'a' also has the same values as 'b'. And moreover, when I declare 'a'

char a[21];

inside function unter(), I'm getting some junk value for 'b'(as output). Care to explain how?

+2  A: 
b = strcat(a, str_temp);

is probably what's causing your issue, since the return value from strcat() is the first parameter that was passed to it, hence why you're seeing a and b becoming equal, since b is getting set to a in that call.

Amber
+2  A: 

a is a char array and b is a pointer that points to a, so when printing them, they always print the same thing. When you move the declaration for a into unter, it is destroyed when unter returns, leaving b a dnagling pointer, so you get garbage when you print it.

Chris Dodd
Makes sense. Thanks
halluc1nati0n
A: 

In addition to the other hints provided, you should take notice of the line

b = strcat(b, str_temp);

which seems rather inappropriate for b is merely defined as a char pointer to a single byte storage ("" defines an empty string, i.e. an array of chars with a single element containing '\0')

So when strcat appends to b, it creates a buffer overrun.

Edit:Actually I just noticed that b was assigned to point to a, (thanks to the line preceding the one mentionned) so that would then be ok, since a may have the room for this... It doesn't make sense however, to need the two variables.

Maybe what you do not understand, is that although strcat() returns a pointer, this return doesn't need to be "consumed", it is merely a convenience, for when we chain commands an such. In other words you can simply write:

strcat(a, str_temp);

Not requiring any char * b.

mjv
hmm. End of the day, I'm getting my desired output and I guess I'm fine by it?
halluc1nati0n
A: 

When you define a inside the function, memory for the variable a is allocated on stack. This memory is destroyed when the function exits. Your pointer b is pointing to starting address of a. Now, if you try to access b outside the function, it is pointing to a memory location which is already destructed and contain garbage values. Basically, b becomes a dangling pointer.

Naveen
A: 

If you declare a inside the unter() function, then it is only scoped inside that function. Attempt to print b from outside the function will print junk since it is pointing to a which is already destroyed.

This is a classic example of why you should always make sure to not to point to a local variable from a global one.

Joy Dutta
+1  A: 

strcat() returns the result of the concatenation operation, so

b = strcat(a, str_temp);

results in b pointing to the array a[]. The subsequent strcat() operations effectively do the same, so the end result is that b points to a[] as you observe. If you declare a[] inside unter() it will have local scope to that function, with the result that the global variable b will point to random/undefined memory contents after you exit the call to unter().

It's mildly worth noting that you're doing a lot of work that could be accomplished more easily with

sprintf(a, "%d_from%dto%d", chnum, mynode, neighbor1);
Rob Pelletier
+1  A: 

You can do the whole concatenation and sprintf's in a single line.

char* b="";
void unter()
    {
        int chnum =0, neighbor1=3, neighbor2=5, mynode=4;
        char str_temp[21];
        sprintf(str_temp,"%d_from%dto%d", chnum, mynode, neighbor1);
        b = new char[strlen(str_temp)+1];
        b = strcpy(b, str_temp);
    }

Only funny thing is you must remember to delete b when you are done. The other option is using the a buffer and sprintf directly to it:

char a[21]; 
void unter()
    {
        int chnum =0, neighbor1=3, neighbor2=5, mynode=4;
        char str_temp[21];
        sprintf(a,"%d_from%dto%d", chnum, mynode, neighbor1);
    }
pcdejager