【问题标题】:How are strings handled in C? [duplicate]C语言中的字符串是如何处理的? [复制]
【发布时间】:2014-11-16 22:28:22
【问题描述】:

我使用 64 位 linux 机器,所以我的指针大小是 8 个字节,所以看看下面的代码,我在我的字符串中的 H 之后编写了下面的程序来进行段错误(在 @987654323 @)。但似乎不会发生。使用下面的程序,我认为它会溢出并破坏x 中的内存。下面的程序在我的系统上运行良好,但如果我在strcpy() 中添加另一个字母,则会出现段错误。所以这样的问题显然是系统相关的,但是这个字符串怎么不会让程序崩溃呢?我确实搜索过这样的问题,如果存在一些链接,您也可以重定向我。提前致谢。

int main()
{

int x;
char* c ;

x = 0xF0000000;

strcpy(&c,"ABCDEFGHFFFFFF");
x++;
printf("%X\n",x);

printf("%s\n",&c);

}

【问题讨论】:

  • 我看到你已经声明了一个指针......但它指向什么?
  • 当然它会在编译时出现警告,但它确实给了我如下输出F0000001 ABCDEFGHFFFFFF我现在这绝对是你编写常规程序的方式我只是想看看字符串是如何被复制的你们肯定没有答案。
  • 你的程序只是UB,没什么好争论的。如果您想知道在特定运行中您的情况到底发生了什么,请断开调试器并单步执行它。请注意,使用调试器可能会改变程序的行为。
  • 你在搞乱内存...char* c; 在 64 位拱形上声明了一个包含 8 个字节的指针,但它们没有被初始化,然后你用strcpy(&c 用更多的垃圾覆盖这个指针(它应该会在第 9 个字符之前破坏内存,但是由于内存对齐,您的程序可能很幸运能够幸存)。我看到您正在尝试同时使用x,但不能保证它们以某种方式彼此相邻分配。如果你想搞这种乱七八糟的,试试union type。
  • 问题是你的意图不明确。通常编译器或内存管理器会分配更多的内存(例如字节对齐,内部分配簿记),因此像这样的小溢出不会在操作系统级别触发段错误,因为您的程序只是弄乱了它的一些内部内存(由图书馆管理)。这就是为什么你的程序是“幸运的”。你会在稍后的某个时间得到你的段错误——当你最不期望的时候;-)如果你想调试你的程序内存,试试 valgrind 工具。

标签: c linux string


【解决方案1】:

关于 C 中的指针和内存管理:

  • 您必须手动创建指针
  • 你必须手动分配内存
  • 您必须手动初始化指针以指向分配的内存

表达式

char *c;

只创建指针,但既不为字符分配任何内存,也不初始化指向已分配内存的指针。

你会更好:

char c[20];

c 将表现得像一个指针,但同时您已经分配了一个 20 字节的缓冲区(在main 的堆栈帧中)并且c 指向它的开头。

当使用字符串(字符指针)时,你不会strcpy指向指针的地址,而是指向指针持有的地址:

strcpy(c, "ABCDEFGHFFFFFF");

顺便说一句:表达式"ABCDEFGHFFFFFF" 分配一个常量字符缓冲区,其中包含文字文本和内存中的终止零,并返回其地址。这就是为什么这种使用是合法的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2013-06-21
    相关资源
    最近更新 更多