简体   繁体   中英

Return statement in function never prints to screen

I'm trying to pass in some parameters into one function, store those values into a set of elements in a struct. Then print those values from within the struct, by calling a another function.

Here's what I'm trying to do:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct temp
{
    int num;
    char * name;
    struct temp * nextPtr;
}temp;

temp * test();
char * printTest(temp * print);

int main (void)
{
    test("TV",200);
    struct temp * t;
    printTest(t);
    return 0;
}

temp * test(char * name, int num)
{
    struct temp * mem = malloc(sizeof(struct temp));
    mem->name = malloc(sizeof(strlen(name) + 1));
    mem->name = name;

    mem->num = num;
    mem->nextPtr = NULL;
    return mem;
}

char * printTest(temp * print)
{
    char * output;

    output = malloc(sizeof(struct temp));
    print = malloc(sizeof(struct temp));

    sprintf(output,"It's name is %s, and it costs %d",print->name,print->num);
    return output; //should print "TV" and costs "200"
}

The function printTest , doesn't seem to print out anything, rather if I hardcore printf within it, it prints null values and zero. However, I tried to print the struct values in the test function, which does work after initializing the values.

For example, if I do printf("%d",mem->num); this does print out a value of 200(In the test function).

But the sprintf and return combination in the last function doesn't result in the same result. Any help would be much appreciated!

You're not capturing the value you return from test, therefore it just gets lost:

int main (void)
{
    //changed to capture return value of test.
    struct temp * t = test("TV",200);
    printTest(t);
    return 0;
}

Also your print function is wrong:

// this now points to the struct you allocated in test.
char * printTest(temp * print)
{
    char * output;

    // you don't really want the size of temp here, you want the size
    // of your formatted string with enough room for all members of the 
    // struct pointed to by temp.
    output = malloc(sizeof(struct temp));

    // you're not using this.
    print = malloc(sizeof(struct temp));

    // you sprintf from a buffer pointing to nothing, into your output buffer
    // writing past the memory you actually allocated.
    sprintf(output,"It's name is %s, and it costs %d",print->name,print->num);

    // return doesn't print anything, it simply returns the value that your
    // function signature specifies, in this case char *
    return output; //should print "TV" and costs "200"
}

Try this, you'll take the pointer you allocated, and use printf to write a formatted string to stdout:

// we're not returning anything
void printTest(temp * print ){
    if (temp == NULL ){
        // nothing to print, just leave.
        return;
    }

    printf("It's name is %s, and it costs %d",print->name,print->num);
    return;
}

Also some notes about your test function:

// char is a pointer to a string, from your invocation in main, this is
// a string stored in static read only memory
temp * test(char * name, int num)
{
    // you malloc memory for your struct, all good.
    struct temp * mem = malloc(sizeof(struct temp));

    // you malloc space for the length of the string you want to store.
    mem->name = malloc(sizeof(strlen(name) + 1));
    // here's a bit of an issue, mem->name is a pointer, and name is a pointer.
    // what you're doing here is assigning the pointer name to the variable 
    // mem->name, but you're NOT actually copying the string - since you 
    // invoke this method with a static string, nothing will happen and
    // to the string passed in, and you'll be able to reference it - but
    // you just leaked memory that you allocated for mem->name above.
    mem->name = name;

    // num is not apointer, it's just a value, therefore it's okay to assign
    // like this.
    mem->num = num;
    mem->nextPtr = NULL;
    return mem;
}

Try this instead:

temp * test(char * name, int num)
{
    struct temp * mem = malloc(sizeof(struct temp));

    // we still malloc room for name, storing the pointer returned by malloc
    // in mem->name
    mem->name = malloc(sizeof(strlen(name) + 1));
    // Now, however, we're going to *copy* the string stored in the memory location
    // pointed to by char * name, into the memory location we just allocated, 
    // pointed to by mem->name
    strcpy(mem->name, name);

    mem->num = num;
    mem->nextPtr = NULL;
    return mem;
}

There were many more problems than at first blush. Here is a cleaned up version. You cannot assign a string (eg mem->name = name; ). You can either allocate for mem->name and then strncpy name to it, or use strdup to allocate and copy at once. In printTest , you must allocate space for output sufficient to hold both the static part of the format string plus print->name and print->num . Look over the following and let me know if you have question.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct temp
{
    int num;
    char * name;
    struct temp * nextPtr;
}temp;

temp * test(char * name, int num);
char * printTest(temp * print);

int main (void)
{
    struct temp * t = test("TV",200);
    // struct temp * t;
    printf ("%s\n", printTest(t));
    return 0;
}

temp * test(char * name, int num)
{
    struct temp * mem = malloc(sizeof(struct temp));
    // mem->name = malloc(sizeof(strlen(name) + 1));
    // mem->name = name;
    mem->name = strdup (name);

    mem->num = num;
    mem->nextPtr = NULL;
    return mem;
}

char * printTest(temp * print)
{
    char *output = NULL;

    // output = malloc(sizeof(struct temp));
    // print = malloc(sizeof(struct temp));

    output = malloc (strlen (print->name) + sizeof print->num + 30);

    sprintf(output,"It's name is %s, and it costs %d",print->name,print->num);

    return output; //should print "TV" and costs "200"
}

Output

$ ./bin/struct_rtn
It's name is TV, and it costs 200

Additionally, sprintf outputs to a string. It does not output to standard out, ie print to the screen, unlike printf which does. You probably want to call printf or puts on your output string.

this line: 'sprintf(output,"It's name is %s, and it costs %d",print->name,print->num)' needs some significant modification. 1) the source fields" print->name and print->num are within an allocated segment of memory However, they have never been set to any specific value, so they contain trash. The destination pointer 'output' points to an allocated memory area, however that area is no bigger that the source area, (and generally, it is expected to be formatted as a 'temp' struct, not as one long string. and because it is only the size of a temp struct, there will be no room for all the extra characters in the sprintf format parameter. Result will be undefined behaviour as the output from sprintf will overrun the allocated memory area

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM