-1

I am trying to access a const char* created in function1 in function2 in order to use it for some operations. It has to be in a different function for several reasons.

I've tried using this code in function2:

const char* str[1024] = { function1() };

but I had no success whatsoever. If I try

printf("%s\n", str[1]);

in function2, it just prints (null).

I've also tried using malloc, but I had no success.

//main function {it does its thing, it wouldn't interest us}
//function1 {it creates a const char* var[1024];)
//function2 {here I want to use the const char* var[1024]; from function1}

Observation: In function1, the const char* prints just fine what it needs to print.

I wish I could find a way to solve this. Thank you for your patience!

Later edit for code:

const char* function1()
{
    lang = fopen("lang.csv", "r");
    int i = 0;
    char line[1024];
    const char* word[1024];
    char num[] = { 1 , 2 };
    while (fgets(line, 1024, lang))
    {
        char* tmp = _strdup(line);
        printf("Field 1 would be %s\n", getfield(tmp, num[0])); // NOTE strtok clobbers tmp
        word[i] = getfield(tmp, num[0]);
        i++; 
        free(tmp);
    }
    printf("%s\n", word[1]); //prints successfully
    fclose(lang);
    return NULL;
}

int function2() {
    const char* word[1024] = { function1() };
    printf("%s\n", word[1]); // failure, prints (null)
}
Amurg
  • 27
  • 1
  • 6
  • 1
    You _describe_ code you have tried and _described_ the results. How about posting the actual code you tried. It may make it much more clear what you are trying to do because `const char*` is a data type - you cannot "_call_" a data type, so it is entirely unclear what you are asking. Presumably you simply mean you want to _access_ the array rather then _call_ it? If so, what kind of access do you wish to do - read or write or both? – Clifford Aug 11 '19 at 12:19
  • Possible duplicate of [Returning string from C function](https://stackoverflow.com/questions/25798977/returning-string-from-c-function). –  Aug 11 '19 at 12:23
  • 2
    This is an X-Y problem. You are describing the problem you are having with _your_ solution to some other problem you are not telling us about. Describe what you are actually trying to achieve, rather then how you are trying to achieve it. – Clifford Aug 11 '19 at 12:23
  • @Clifford Thank you for correcting my post and all the suggestions! I do appreciate a lot! I edited it by adding the two functions. What I am trying to achieve is using the const char* word[1024] from function1 in function2 (I want it to have the same values like the one in function1) – Amurg Aug 11 '19 at 12:26
  • 5
    Why does `function1` return `NULL`? –  Aug 11 '19 at 12:32
  • @Clifford Therefore, I think that saying that I want to access it is more accurate. I just want to read. – Amurg Aug 11 '19 at 12:34
  • @DavidCullen The function forces me to return a value, so I needed something to return – Amurg Aug 11 '19 at 12:35
  • 1
    @melpomene Apologize, I wanted to say "access". I am just very tired. – Amurg Aug 11 '19 at 12:48
  • Are you aware of the differences between local and global variables or arguments passed to a function and their return value? There seems to be some misunderstandings of basic language features that may be too broad to address in a simple Q&A. – Bob__ Aug 11 '19 at 12:53
  • This whole question makes little sense. `word` is not a `const char *` (a pointer to const char), it is an array of pointers. The `{ function1() }` initializer only provides a single value, setting the first element of the array. `word[1]` is `NULL`, as expected. (And `function1` always returns `NULL` anyway.) – melpomene Aug 11 '19 at 12:53
  • I think the edit makes it clear enough what is being asked - assuming English as a foreign language - and this question might usefully be re-opened. The flaws with the code are numerous, but the intent is clear. It seems to me that the intent is that `function1()` creates a list of words from a specific field in each line of a file. `function2()` requires read access to the generated list - though here it only access the first word in the list - I would assume that this is not yet complete?. I was working on an answer when the issue got closed - too bad. – Clifford Aug 11 '19 at 12:56
  • @Clifford I don't think it's that simple, given that OP doesn't even know what return values are. – melpomene Aug 11 '19 at 12:57
  • @Bob__ I am aware of the local and global variables and arguments passed to a function, but I admit I've never understood from online explanations what the return value does, so I've always used return 0 without any problems, until now. I have very few experience in coding so please bear with me... – Amurg Aug 11 '19 at 12:59
  • @Clifford Yes, you are right, that's it. – Amurg Aug 11 '19 at 12:59
  • 2
    @melpomene : It is clear he is a novice, but that is not a crime. Answering this question is an opportunity to educate him, not ignoring him for what he does not know, and does not know he does not know. He might however clarify the question for it to be reopened. It is as simple as that in that the intent of his code is clear (enough), even if it is semantically nonsense. – Clifford Aug 11 '19 at 13:01
  • 1. The question is already open again. 2. SO does not exist to tutor people; it is there to provide answers to specific questions. I think OP is asking the wrong question. – melpomene Aug 11 '19 at 13:03
  • @Amurg : I suggest that you either post a new, clearer question or that you edit this one and hope that it gets enough votes to re-open. If you create a new one, you should delete this one if you are able. – Clifford Aug 11 '19 at 13:03
  • @melpomene : I already pointed that out - it _was_ an X-Y problem, but in good faith he posted his code thus far like I asked, so it is far less so now. Improved, if not perfect. – Clifford Aug 11 '19 at 13:07
  • This sounds like a scope issue, @Amurg. Provided `function1` and `function2` are defined within the same source file, you may want to give word [file scope](https://stackoverflow.com/a/21898886/5386374), and providing a mechanism to allocate and deallocate it as needed. This would make it easier to use as an internal buffer, as seems to be your intent. – Justin Time - Reinstate Monica Aug 11 '19 at 15:20

2 Answers2

1

This is a stand-alone example that shows you how to allocate your word list from the heap and return it to another function:

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

#define WORD_COUNT 1024

const char **function1(void) {
    const char **word = malloc(sizeof(const char *) * WORD_COUNT);
    for (int index = 0; index < WORD_COUNT; index++) {
        // You would replace these lines with your getfield code
        char number[20];
        snprintf(number, sizeof(number), "%d", index);
        word[index] = strdup(number);
    }
    // We return word here because that is how we pass the result to the caller
    return word;
}

void function2(void) {
    const char **word = function1();
    printf("word[1] = %s\n", word[1]);
}

int main(void) {
    function2();
    return 0;
}

Output

word[1] = 1

Warning

The program allocates memory via malloc and strdup but does not call free to de-allocate it. This could result in memory leaks.

1

You have a number of problems.

  • word is not static so does not exist outside of function1()
  • Even if word were static, its elements point to content in tmp which is free()'d before function1() returns.
  • function1() returns NULL - presumably the intent was to return the pointer word? But that would be incorrect in any event for all the reasons above.
  • function2() assigns as many word pointers as there are lines in the file, which may be more than the allocated 1024.

This problem can be solved in a number of ways. One way is to pass the array of pointers to words to function1() and have function1() allocate space for each word. This then requires function2() to take responsibility for freeing the allocated words when done. Not a method I'd normally recommend, but the alternative is to define some arbitrary fixed maximum length for each word.

I have made some assumptions about the semantics of getfield() and removed the array num as it seems to serve no purpose in the original code.

int function1( const char** words, size_t max_words )
{
    FILE* lang = fopen( "lang.csv", "r" );
    char line[1024];
    size_t i = 0;
    while( i < max_words && fgets( line, 1024, lang ) != NULL )
    {
        printf( "Field 1 would be %s\n", getfield( line, 1 ) ) ;
        const char* tmp = getfield( line, 1 );
        char* word = malloc( strlen( tmp) + 1 ) ;
        strcpy( word, tmp ) ;
        i++ ;
    }
    printf( "%s\n", words[1] ); //prints successfully
    fclose( lang );

    return i ;
}

int function2() 
{
    char* word[1024] = {0} ;

    // Fill the word list
    int count = function1( word, sizeof(word) / sizeof(*word) ) ;

    // Print first word
    printf( "%s\n", word[1] ); //failure, prints (null)

    // Delete list elements allocated by function2()
    for( int i = 0; i < count; i++ )
    {
        free( word[i] ) ;
    }

    return count ;
}
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Conversion from `char *word[1024]` to `const char** words` is not implicit (sadly) :/ You only can convert it implicitly to `char * const * words`. – KamilCuk Aug 11 '19 at 13:59