将数据存储在堆栈中?

时间:2018-10-31 03:51:38

标签: c stack printf const memory-layout

我要回答有关printf接受char *的问题,所以我建立了一个小测试程序并提出了自己的问题。使用GCC 6.3在codechef.com/ide上编译

Pass the char* directly to printf 我认为问题是在问“缺少” const限定词发生了什么吗? http://man7.org/linux/man-pages/man3/printf.3.html

char * str1 = "This is string 1\n";
char str2[] = "This is string 2\n";
int main(void) {

    char str3[100] = "This is string 3\n";
    char * str4 = "This is string 4\n";

    str3[8] = 'c';

    printf(str1);
    printf(str2);
    printf(str3);
    printf(str4);

    return 0;
}

输出:

这是字符串1

这是字符串2

这是ctring 3

这是字符串4

我当时正在考虑程序的内存布局,我感到更加困惑。 https://www.geeksforgeeks.org/memory-layout-of-c-program/

str1是指向字符串文字“这是字符串1 \ n”的指针。 str1位于数据中,并指向位于??中的字符串文字。 (我假设还初始化了数据段) How is read-only memory implemented in C?

就内存布局而言,

str2类似于str1。

str3变得很有趣。 str3驻留在堆栈中,宽度为100个字符,并通过声明/赋值分配给char [0] ='T',char [1] ='h'等。这不应该是常量。 str3的声明和赋值是在堆栈上声明100个字符,并从数据(rom数据段或初始化的数据段或文本?)中为它们分配值。

str4是堆栈上的一个指针,指向数据段内存。就像str1和str2一样,不太有趣。

然后分配str3 [8] ='c'只是为了测试/验证/证明str3的堆栈内存不是仅在printfing之前读取的。

我希望1,2,4可以工作,但是为什么3可以工作(甚至没有编译器警告??)。我可能会错误地假设const是“只读”的同义词,因为如果我刚刚写的话,str3就不可能是“只读”。

Is there a read only memory in the stack for const variable declared in a function?

有人可以向我解释为什么str3没有引发警告或错误吗? str3不是const char *,要么编译器对其进行了优化(将赋值更改为“ This is ctring 3 \ n”),要么警告被抑制(似乎不太可能),或者我对cost关键字有基本的误解。堆栈内存常量如何?也许我的一个或多个假设是错误的。

1 个答案:

答案 0 :(得分:3)

当函数原型包含指向const限定对象的指针时,这意味着该函数承诺不会尝试修改指向的内容。这并不意味着只能接受指向const对象的指针(无论可能是什么)。

另一方面,如果原型包含指向 const不合格的对象的指针,则意味着它可能会尝试修改其内容。在这种情况下,将指针传递给不可变对象将导致未定义的行为。如果尝试将指针传递到const限定对象(如果启用警告),则大多数编译器都会警告您,因为const限定的指针可能指向不可变的对象。

通常来说,您应该将const理解为“我保证不会修改”,而不是“无法修改”。