【问题标题】:array, string, pointer manipulation in C [duplicate]C中的数组,字符串,指针操作[重复]
【发布时间】:2014-09-22 20:44:13
【问题描述】:

据推测,这段代码中有一个错误,但它运行良好并且输出符合我的预期(“hello world”)。 return str有问题吗?

#include <string.h>

char* example(){
    // your code goes here
    char str[12];
    strncpy(str, "hello world", 11);
    str[11] = 0;
    printf("%s\n",str);
    return str;
}

int main() {
    char * check = example();
    return 0;
}

输出:

Success time: 0 memory: 2248 signal:0
hello world

【问题讨论】:

  • 您在寻找null byte '\0' 吗?在任何情况下,您都不必使用 strncpy 手动设置空字节。
  • strncpy 你做@C.B.它会在处理 n 个字符时停止,并且可能不会设置空终止符。在这种情况下,它肯定不会。
  • @KeithNicholas 仅当源长度超过要复制的 num 个字节时,对吧?
  • @C.B,对,就像他一样。 11 是字符数,所以他错过了复制 0
  • @KeithNicholas 对,我的错

标签: c arrays pointers runtime


【解决方案1】:

大问题!

   return str;

str 是一个局部变量。您不能将其地址传递给调用者,因为它所指向的内容不能保证是您在example 中分配给它的内容。如果您将str 定义为static,这将不是问题:

static char str[12];

编辑 1

你也可以malloc内存为str

char *str = malloc(12);

如果选择这种方式,一定要记得free动态分配的内存,防止内存泄漏。

另一种方法是使str全局:

char str[12];

char *example(void)
{
    ...
}

不过,通常最好尽可能限制变量的范围。

编辑 2

还有一种方法是让调用者为字符串分配内存。下面是一个例子:

void example(char *str, size_t length)
{
    strncpy(str, "hello world", length);
    str[length - 1] = '\0'; // Guarantee string '\0' terminated
}

int main(void)
{
    char str[12];
    example(str, sizeof(str));
    printf("%s\n", str);

    exit(EXIT_SUCCESS);
}

这种方法的问题在于,调用者一般不知道要返回的字符串的长度。

【讨论】:

  • 正确,但不确定我是否会推荐静态。
  • @KeithNicholas 你会推荐mallocing 还是让它全球化?
  • 我不推荐全局,因为它与静态基本相同,我要么传入一个 char* ,然后填充它,并将分配问题与函数分开,要么返回一个malloc'd char*
  • 使其成为静态意味着您只能有效地调用该函数一次;此后,任何其他调用都将共享返回值。在这里,返回的字符串是常量,所以它并不重要,但大多数函数返回不同的值。为此,为了线程安全,静态变量是不可取的。通常最好让调用代码提供空间(最好的设计通常需要一个指针和最大长度)。使函数使用malloc() 也可以,但将责任放在调用代码上以释放分配的内存(但strdup() 正是这样做的。
  • @JonathanLeffler 很棒的建议。
【解决方案2】:

错误是example() 函数返回一个指向本地数组str 的指针。当函数返回时,它的所有局部变量都不再有效,使用指向它们的指针是未定义的行为。

这显然是有效的,因为main() 函数实际上从未对返回的指针做任何事情。如果你把

printf("%s", check);

main() 你可能会在那里得到垃圾输出。

【讨论】:

    猜你喜欢
    • 2011-03-13
    • 2013-06-07
    • 2021-06-28
    • 1970-01-01
    • 2021-08-12
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多