【问题标题】:Printing manually crafted string not working打印手工制作的字符串不起作用
【发布时间】:2017-08-27 01:07:50
【问题描述】:
int main() {
  char a = 'b';
  char* c = &a;
  *c = 'a';
  *(c+1) = 'j';
  *(c+2) = '\0';

  printf("%s\n", (char*)&a);
}

它会打印字符“a”和“j”,但随后会打印垃圾,似乎忽略了空终止字符。

为什么?

【问题讨论】:

  • 您认为地址c+1c+2 是什么?更相关的是,为什么您认为写信到这些位置是安全的?
  • 未定义的行为 - 你没有为 c[1]c[2] 分配空间(你用晦涩的 *(c+1)*(c+2) 表示法编写)。
  • 这是因为我正在检查具有非常相似逻辑的反编译代码,但它没有分配缓冲区......我应该进一步调查。现在我知道这应该会爆炸,因为它没有先前分配的大小。我应该复习我的 C 知识。

标签: c string memory


【解决方案1】:

您所做的会导致未定义行为,因为 char 指针 c 没有指向能够存储您的字符串的内存块。

因此,当您将指针前进 1 或/和 2 时,您访问的内存与指针 ca 指向的位置无关,您将导致分段错误,或者访问您的内存程序已分配,但这是随机且不好的。


您需要为a(多少?2 个字符,加上空终止符)分配空间,这为您提供了一个大小为 3 的字符数组。然后将指针 c 设置为 a 的开头.现在您可以使用c 进行指针运算,从 0 到 2(数组大小 - 1),并通过指针分配所需的字符和空终止符。

#include <stdio.h>

int main() {
  char a[3];
  char* c = a; // set 'c' point to the start of the array 'a'
  *c = 'a';
  *(c+1) = 'j';
  *(c+2) = '\0';

  printf("%s\n", a);
}

aj

【讨论】:

  • 它没有用。还在打印垃圾。但是感谢您闪电般的快速回复。
  • printf("%s\n", (char*)&amp;a); 应该是printf("%s\n", a);
  • 另外,您可以使用 malloc() 动态分配内存,这意味着您可以在程序运行时为数据保留空间,而不是硬编码数量。记住在 malloc() 内存时也要使用 free()。请参阅此内容以供参考:en.cppreference.com/w/c/memory
  • 这个方法使用a指针只是一个指向实际数组元素的指针
【解决方案2】:

因为你需要分配一个缓冲区,所以你不能只取一个指针并写入那个地址。

我猜你这样做是为了学习,因为你可以这样做:

char *a = "bj\0";
printf("%s\n", a);

如果你想附加字符,我强烈建议使用 std::string。 否则,您将不得不这样做:

char a[3]; // You need to allocate a defined size!
char* c = a;
*c = 'a';
*(c+1) = 'j';
*(c+2) = '\0';

printf("%s\n", (char*)&a);

或者没有演员表:

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

对不起,我没有编译,所以可能有错别字。

【讨论】:

  • 这是因为我正在检查具有非常相似逻辑的反编译代码,但它没有分配缓冲区......我应该进一步调查。现在我知道这应该会爆炸,因为它没有先前分配的大小。泰。
  • 是的,有一个错字,请参阅我的回答 MGambsy,然后告诉我您的想法。这个char* c = &amp;a; 无法编译。
  • std::string 在 C 中? *(c+1) 将添加 char [3] 因为 &a 的类型为 char [3]
  • @gsamaras 你说得对,我编辑了它,但我认为获取 char 数组的第一项的地址没有意义(char *c = &a[0]),我用“char *c = a”编辑了我的答案,这更像是它的本质。我的意思是你的回答有效,但我只是认为它增加了更多的复杂性。
  • 同意@MGamsby。此外,您可以像我的一样调整您的打印功能,以最大限度地降低复杂性。你现在喜欢我的回答吗,我更新了!我会支持你的,因为你表现出了努力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 2021-11-11
  • 2020-07-09
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
相关资源
最近更新 更多