带有字符串文字的 C 空指针

发布于 2024-10-22 12:17:15 字数 565 浏览 7 评论 0原文

使用 ARM、C 编译器,我可以成功编译并运行以下内容:

static char * myString = 0;

void myfunc(int x){

   if (x <= 0)
       myString = "Hello World";
   else 
       myString = "This is a different string with a different length";

}

int main(){

    myfunc(-1);
    printf("%s\n", myString);
    myfunc(2);
    printf("%s\n", myString);
}

为什么这有效?

指针不应该是NULL指针吗?

至少,字符串文字不应该分配在只读内存位置吗?

编辑:它是一个 C++ 编译器

编辑2:为什么在 myfunc 超出范围后,字符串文字存在于静态范围中?字符串文字是否未在堆栈上声明?它们什么时候被释放?

谢谢!

Using an ARM, C compiler, I can successfully compile and run the following:

static char * myString = 0;

void myfunc(int x){

   if (x <= 0)
       myString = "Hello World";
   else 
       myString = "This is a different string with a different length";

}

int main(){

    myfunc(-1);
    printf("%s\n", myString);
    myfunc(2);
    printf("%s\n", myString);
}

Why does this work?

Shouldn't the pointer be a NULL pointer?

At the very least, shouldn't the string literal by allocated in a read-only memory location?

EDIT: its a C++ compiler

EDIT2: Why does the string literal exist in static scope, after myfunc has gone out of scope? Are string literals not declared on the stack? And when do they get deallocated?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

若无相欠,怎会相见 2024-10-29 12:17:15

这两个字符串分配在只读存储器中并且完全不同。但是你使用同一个指针来指向它们中的每一个......有什么不明白的?

请记住,char* 只是一个指针。它是可变的(非常量)。

char* p = 0;
p = "Hello"; //OK
p = "Jo" //OK;
p[0] = 'X' //OOPS, now THIS is bad (undefined behavior)

编辑后:

不,字符串文字具有静态存储持续时间(与所有其他文字不同),它们不是在 stack 上创建的。它们将一直存在直到程序终止。

The two strings ARE allocated in read-only memory and are completely different. But you use one and the same pointer to point to each of them... What's not to understand?

Remember, char* is just a pointer. It is mutable (non-const).

char* p = 0;
p = "Hello"; //OK
p = "Jo" //OK;
p[0] = 'X' //OOPS, now THIS is bad (undefined behavior)

After your edit:

No, string literals have static storage duration (unlike all other literals), they aren't created on stack . They will exist till program termination.

诗化ㄋ丶相逢 2024-10-29 12:17:15

如果你要声明,

char const *MyString = 0;  

那么你会遇到麻烦,因为 const 指针无法重新分配。字符串文字是常量。

       .section        .rodata
.LC0:
        .string "Hello World"
        .align 8
.LC1:
        .string "This is a different string with a different length"
        .text

文字串数据被组装在只读数据部分中。

if you were to declare

char const *MyString = 0;  

then you would have troubles as the const pointer cannot be reassigned. String literals are constants.

       .section        .rodata
.LC0:
        .string "Hello World"
        .align 8
.LC1:
        .string "This is a different string with a different length"
        .text

The literal string data is assembled in the read only data section.

人心善变 2024-10-29 12:17:15

常量字符串通常在程序的“数据段”中创建,并且指向它们的指针始终有效(字符串“对象”在程序生命周期内有效)。所以不。文字字符串不是在堆栈上创建的。

我相当确定 C.Happy 编码中的语义是明确定义的

Constant strings are generally created in the "data segment" of the program and the pointers to them are always valid (the string "objects" are valid for the program lifetime). So no. The literal strings are not created on the stack.

I am fairly certain the semantics are well-defined in C.

Happy coding.

节枝 2024-10-29 12:17:15

是的,但是您为它分配了一个指向字符串文字的指针,因此它指向两个字符串数组之一。

It is, but then you assign a pointer to the string literal to it, so it points to one of the two string arrays.

汹涌人海 2024-10-29 12:17:15

myString 是一个指针变量,您故意将其设置为指向存储两个字符串常量之一的内存。

myString is a pointer variable, you are deliberately setting it to point to the memory where one of your two string constants are stored.

滴情不沾 2024-10-29 12:17:15

最初它是一个空指针。但您自己显式更改该指针并使其在 myfunc 函数内非空。

在第一次调用 myfunc 时,您显式地使指针指向字符串文字 “Hello World”。当然,在那一刻之后,指针不再为空。

字符串文字确实分配在只读内存位置(至少在概念上)。但是,在 C 和 C++ 中,您都可以使用 char * 指针指向字符串文字(即不需要 const char *)。只要您不尝试修改文字,就可以使用 char * 指针指向字符串文字。您的代码不会尝试修改任何内容,因此没问题。

C 和 C++ 中的字符串文字具有静态存储持续时间。所以不,它们不是“在堆栈上”分配的。它们始终分配在静态内存中,这意味着它们永远存在 - 只要您的程序正在运行。

PS为了更完整地回答你的问题,你必须解释为什么你希望你的指针保持为空。

PPS int main,而不是 void main

Initially it is a null-pointer. But you yourself explicitly change that pointer and make it non-null inside myfunc function.

In the first call to myfunc you explicitly make your pointer to point to string literal "Hello World". After that moment the pointer is, of course, no longer null.

String literals are indeed allocated in a read-only memory location (at least conceptually). However, in both C and C++ you are allowed to point to string literals with char * pointers (i.e. const char * is not required). It is OK to just point to string literal with char * pointer, as long as you are not trying to modify the literal. Your code does not make any attempts to modify anything, so it is OK.

String literals in C and C++ have static storage duration. So no, they are not allocated "on the stack". They are always allocated in static memory, meaning that they live forever - as long as your program is running.

P.S. In order to answer your question more completely, you have to explain why on Earth you expect your pointer to remain null.

P.P.S. int main, not void main.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文