-2

I am currently working on a program with the Dante Brooklyn II board from audinate. I am trying to use a void return function from the Dante API - foo() - that needs to have 3 various structs passed in as well as 2 strings. I have another function get_value_by_key() which returns the string value that I need. I initially tried calling on the program like so:

    foo(struct, struct, struct, get_value_by_key(key1), get_value_by_key(key2);

When I run it this way, the program twists the returned strings of get_value_by_key() and crashes the entire program. I have, however, found an alternative that works, but it is longer and I would like to not waste the extra processing power. The alternative is here:

    char value1[15], value2[15];
    strcpy(value1, get_value_by_key(key1));
    strcpy(value2, get_value_by_key(key2));
    foo(struct, struct, struct, value1, value2);

I cant seem to decipher why the Brooklyn board shuts down with the first command, and not the second. Any help at all would be much appreciated. This is the code for get_value_key(). Pretty simple logic here:

    char * get_value_by_key(command_t command, char key[50]){
         int i;
         char value[50];
         for(i = 0; i < NUM_PARAMETERS; i++){
             if(strcmp(user_command.command_parameter[i].key, key) == 0){
                 strcpy(value, user_command.command_parameter[i].value);
             }
         }
         return value;
     }
  • 1
    No idea what a Brooklyn board is - can you please edit the question and add some context :) ? – Morten Jensen Sep 07 '18 at 16:57
  • Where do you allocate storage for value1 and value2? – stark Sep 07 '18 at 16:57
  • In your second attempt, you need to malloc some memory to those char* pointers before you strcpy to them. But I suspect your problem is earlier. Is get_value_by_key() something you wrote? How does it allocate the string that it returns? If it is anything more complex that returning a pointer into a pre-built table of strings, then you almost certainly need a malloc there as well. – Gem Taylor Sep 07 '18 at 17:02
  • did you try to cast the return strings as follow? `foo(struct, struct, struct, (char *)get_value_by_key(key1), (char *)get_value_by_key(key2);` – Simo Sep 07 '18 at 17:02
  • can you please share the function prototypes of foo and get_value_by_key – static_cast Sep 07 '18 at 17:04
  • 2
    Step 1: Enable compiler warnings to save time. `strcpy(value2, get_value_by_key(key2));` should complain. – chux - Reinstate Monica Sep 07 '18 at 17:19
  • @MortenJensen: Dante is a proprietary set of protocols for networked professional audio streaming. Where "audio streaming" in this context does not refer to the iTunes / Spotify kind of streaming but the professional real-time multi-channel audio kind, i.e. not as a replacement for CDs but as a replacement for cabling in a TV studio or on live music stage. Audinate is the company that markets Dante. The business model is that the protocol is closed and proprietary and only hardware implementations are available in the form of chips and boards that implement the protocol and can be integrated … – Jörg W Mittag Sep 07 '18 at 17:34
  • … into your own devices. Brooklyn II is one of those boards: https://audinate.com/products/manufacturer-products/dante-brooklyn-ii – Jörg W Mittag Sep 07 '18 at 17:35
  • [Set up your compiler warnings](https://ideone.com/nfkzB9) – n. m. could be an AI Sep 07 '18 at 18:35

2 Answers2

2

Your get_value_by_key function is broken -- it is returning a pointer to a local variable (value) which is destroyed when the function returns. So you get undefined behavior when you try to read the string -- it might still be there but might have been overwritten by something else.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
1

This looks like a mistake:

char * value1, value2; /* value1 is a char*, value2 is a char */
strcpy(value1, get_value_by_key(key1));
strcpy(value2, get_value_by_key(key2));

You are copying data into value1 and value2, but you have not allocated memory for the strings - just the pointer and the char. NOTE: only value1 is a char*, and value2 is a single char. If you want to declare both a char*, you need to write:

char *value1, *value2;

The code below should work without crashing (assuming get_value_by_key() returns a char*), but I don't know how you want to allocate the space. On the stack, the heap or in static RAM ?

char value1[128], value2[128];
strcpy(value1, get_value_by_key(key1));
strcpy(value2, get_value_by_key(key2));

EDIT: (edited after new info in the comments)

Please post the code for get_value_by_key.

I am betting it uses a static buffer to hold the string/char-array it returns a pointer to. That would mean the content gets destroyed after the second call and that could be a problem.

EDIT2:

If that is indeed the real source, then you are returning a pointer to something allocated on the stack - strictly verboten!!

See returning a local variable from function in C

Morten Jensen
  • 5,818
  • 3
  • 43
  • 55
  • That's not the portion of the code that is not working, that actually worked just fine. What was not working was the first segment of code. – McKenzie Callahan Sep 07 '18 at 17:19
  • take that back, I copied it down wrong because I've been looking at this for way too long and my eyes are fried – McKenzie Callahan Sep 07 '18 at 17:26
  • 1
    @McKenzieCallahan I promise you, that is not going to work. Those pointers point at what? You are using them uninitialized and using a char as a char-pointer. Your compiler must whine with warnings? – Morten Jensen Sep 07 '18 at 17:26
  • I edited the code up above...I copied it wrong the first time, and didn't bother to check what I had wrriten – McKenzie Callahan Sep 07 '18 at 17:27
  • @McKenzieCallahan that fixes that then :) I will edit my post with a new suggestion – Morten Jensen Sep 07 '18 at 17:28
  • @McKenzieCallahan If that is indeed the real source, then you are returning a pointer to something allocated on the stack - strictly verboten. See https://stackoverflow.com/questions/4824342/returning-a-local-variable-from-function-in-c – Morten Jensen Sep 07 '18 at 17:36
  • 1
    @McKenzieCallahan I think you need to research how memory gets allocated in C. All variables created in a function, are destroyed when it returns (unless the vars are marked static). So you can't return a pointer to a string allocated on the stack in a function call and expect it to work. Allocate on the heap or save the data in statically allocated memory, or pass a pointer to memory allocated on the stack, when calling `get_value_by_key()`. – Morten Jensen Sep 07 '18 at 17:47