функция возвращает адрес локальной переменной [-Wreturn-local-addr] sprintf

#arrays #c #string #printf #return-type

Вопрос:

у меня есть новый c, и я пробую sprintf вместе с указателями. все, что я получаю в консоли, — это return buf; как и, пожалуйста, помогите мне с этим кодом.

 #include <stdio.h>
char* stringa(char* str);
int main()
{
    char* ss = "123";
    stringa(ss);

    return 0;
}

char* stringa( char* str)
{
    char buf [100] ;
    sprintf(buf,"hello %s", str);
    return buf;

}   
 

я пробовал много других способов, таких как sprintf_c, и мой компьютер выключился для серьезного. я изучаю c.

Комментарии:

1. Время жизни переменной buf заканчивается, когда функция stringa возвращается. Простым решением была бы static переменная, например static char buf [100] ; . static переменные будут сохранять свое значение между вызовами функции. Это имеет тот недостаток, что возвращаемое значение stringa будет указывать на один буфер, который перезаписывается при каждом вызове stringa . Вы также должны убедиться, что sprintf запись не будет выполняться после конца buf .

2. en.wikipedia.org/wiki/Dangling_pointer

Ответ №1:

Может быть, это то, что вы хотите

 #include <stdio.h>
char* stringa(char* dest, char* src)

int main()
{
    char buf [100] ;
    char* ss = "123";
    printf("%sn", stringa(buf, ss));

    return 0;
}

char* stringa(char* dest, char* src)
{
    sprintf(dest,"hello %s", src);
    return dest;
}
 

Комментарии:

1. Я предлагаю также передать sizeof(buf) в качестве аргумента stringa , чтобы разрешить предотвращение переполнения буфера.

2. спасибо, это работает, я хочу знать, что столкнулся со всеми проблемами, потому что мой бафф уничтожался после завершения функции, и если бы у меня был бафф в качестве глобальной переменной, сработал бы он просто любопытно

3. @Захир да, глобальный вариант сработал бы, но … избегайте глобальных значений

Ответ №2:

В функции ‘char * stringa (char * str)’ вы не выделяете место в heep для массива символов ‘buf’, вы выделяете место в стеке для этой переменной. (это означает, что после завершения функции переменная ‘buf’ будет удалена, потому что она будет вне области видимости) поэтому вы должны попросить компилятор выделить место в памяти для этого массива, я рекомендую использовать malloc ()

пример:

 char* stringa( char* str)
{
char *buf  = (char*)malloc(sizeof(char) * 100);
sprintf(buf,"hello %s", str);
return buf;
}
 

Ответ №3:

 char* stringa( char* str)
{
    char buf [100] ;
    sprintf(buf,"hello %s", str);
    return buf;

}
 

Проблема с этим кодом заключается в том, что buf char массив является локальным для stringa функции. Когда функция возвращается, память, занятая buf массивом, больше недействительна (например, ее можно повторно использовать позже для хранения содержимого других переменных, массивов и т. Д.).

Поэтому, когда функция возвращается, вы даете вызывающей стороне указатель на мусорную память, на недопустимые данные. Компилятор C пытается помочь вам с этим предупреждающим сообщением; он сообщает вам: «Извините, вы пытаетесь передать вызывающей стороне адрес локальной переменной (т. Е. Массива buf char), который больше недействителен при завершении функции».

Чтобы устранить эту проблему, одним из вариантов может быть выделение char массива для выходной строки на сайте вызова и позволить вызываемой stringa функции записывать данные в массив, предоставленный вызывающим объектом:

 #include <stdio.h>

char* stringa(char* dest, const char* str);

int main()
{
    const char* ss = "123";
    char buf[100];
    stringa(buf, ss);

    return 0;
}

/* Write the final message into 'dest'.
 * Return the same dest address.
 */
char* stringa(char* dest, const char* str)
{
    /* Note: better using a safe string function 
     * to prevent buffer overflows (e.g. sprintf_s),
     * passing the maximum destination array size as well.
     */
    sprintf(dest,"hello %s", str);
    return dest;    
}   
 

Обратите внимание, что я также добавил некоторые const s в ваш код, чтобы обеспечить некоторую корректность для входных строк, доступных только для чтения.