Initialize structure pointers in function in C

I'm new to C, and I'm a little confused about the correct way to initialize structure variables that are pointers inside a function. Is this style sufficient or do I need to allocate memory before assigning s-> str? Thank you for your answers, sorry if the question is not clear, as I am very new to this language.

typedef struct Mystruct{
    const char* str1;
    const char* str2;
}mystruct;

mystruct* mystruct_new(const char* str1, const char* str2){
    mystruct *s = (mystruct*)(malloc(sizeof(mystruct)));
    s->str1 = str1;
    s->str2 = str2;
    return s;
}
+4
source share
4 answers

Your function is legal and does nothing wrong. However, you should document it, indicating that the lines are not copied, only pointers.

So, if the transmitted data has a shorter lifespan than the structure itself, you may encounter undefined behavior. Example:

mystruct*func()
{
   char a[]="foo";
   char b[]="bar";

   return mystruct_new(a,b);
}
mystruct*func2()
{
   char *a="foo";
   char *b="bar";

   return mystruct_new(a,b);
}

int main()
{
    mystruct *s = func();
    printf(s->a); // wrong, memory could be trashed
    mystruct *s2 = func2();
    printf(s2->a); // correct
    mystruct *s3 = mystruct_new("foo","bar");
    printf(s3->a); // also correct, string literals have global scope
}

- undefined , s->a , ( func). , s2->a , .

, :

mystruct* mystruct_new(const char* str1, const char* str2){
    mystruct *s = malloc(sizeof(mystruct));
    s->str1 = strdup(str1);
    s->str2 = strdup(str2);
    return s;
}

. free , .

+4

, str str2, , , . , , . , strdup :

mystruct* mystruct_new(const char* str1, const char* str2){
    mystruct *s = malloc(sizeof(mystruct));
    s->str1 = strdup(str1);
    s->str2 = strdup(str2);
    return s;
}

, .

+3

: , - . , , :

mystruct *s = malloc(sizeof(mystruct)); //don't cast result of malloc.

s->str1 , char*,

char *str1 = NULL;

, -, . :

mystruct* mystruct_new(const char* str1, const char* str2){
    mystruct *s = malloc(sizeof(mystruct);

    char* someString = getMyString(); //gets some arbitrary string
    char* str1 = NULL;//just for demonstration
    int length = strlen(someString) + 1;

   //for struct members
    s->str1 = malloc(sizeof(char) * length);
    strcpy(s->str1, someString);

   //For regular pointers
    str1 = malloc(sizeof(char) * length);
    strcpy(str1, someString);

    return s;
}

, = , . , . , , , ( ) , . .

//Makes a copy of the string
s->str1 = malloc(sizeof(char) * length);
strcpy(s->str1, someString);

//copies the address of the original value only!
s->str1 = someString;
+1

strncpy() strcpy(). .

, , , strncpy() strcpy()

mystruct* mystruct_new(const char* str1, const char* str2){
    mystruct *s = malloc(sizeof(mystruct);

    char* someString = getMyString(); //gets some arbitrary string
    char* str1 = NULL;//just for demonstration
    int length = strlen(someString) + 1;

   //for struct members
   s->str1 = malloc(sizeof(char) * length);
   strcpy(s->str1, someString);

  //For regular pointers
  str1 = malloc(sizeof(char) * length);
  strcpy(str1, someString);   // replace with strncpy(str1, someString, bufsize);  where bufsize is the maximum number of characters in your string + 1 for the terminator '\0'.  

  return s;

}

0

Source: https://habr.com/ru/post/1688966/


All Articles