memset 不使用指向字符的指针
Posted
技术标签:
【中文标题】memset 不使用指向字符的指针【英文标题】:memset is not working with pointer to character 【发布时间】:2016-10-11 01:57:23 【问题描述】:以下代码有什么问题? memset 应该与指向要填充的内存块的指针一起使用。但是这段代码在控制台中显示了分段错误(核心转储)的问题
#include<iostream>
#include <cstring>
using namespace std;
int main(int argc, char** argv)
char* name = "SAMPLE TEXT";
memset(name , '*', 6);
cout << name << endl;
return 0;
【问题讨论】:
请勿在此处张贴文字图片。发布文本。 【参考方案1】:您已经绊倒了 C++ 中一个非常古老的向后兼容缺陷,它继承自 C 并且可以追溯到 没有像 const
这样的东西的日子。字符串文字的类型为 const char [n]
,但是,除非您告诉编译器您不需要与 1990 年之前的代码兼容,否则它将默默地允许您设置 char *
变量以指向它们。但它不会允许您通过这样的指针进行写入。实际内存(尽可能)标记为只读;您观察到的“分段错误”错误是操作系统如何报告写入只读内存的尝试。
就语言规范而言,通过非const
指针写入const
数据——但是你设法设置它——具有“未定义的行为”,这是说“程序是不正确,但编译器不必发出诊断,如果你得到一个编译的可执行文件,它可能会做任何事情。” “分段错误”几乎总是意味着您的程序在某处有未定义的行为。
如果我用适当的设置编译你的程序,我会得到一个错误:
$ g++ -std=gnu++11 -Wall -Werror test.cc
test.cc: In function ‘int main(int, char**)’:
test.cc:7:19: error: ISO C++ forbids converting a string constant to ‘char*’
[-Werror=write-strings]
char* name = "SAMPLE TEXT";
^~~~~~~~~~~~~
在您获得足够的技能以了解何时不同的设置更合适之前,请使用-std=gnu++11 -Wall -Werror
或任何与您的编译器等效的东西来编译所有您的 C++ 程序。 (您似乎使用的是 Unix 风格的操作系统,因此这些设置应该可以工作。您可能还需要-g
和/或-O
。)
你的程序可以通过改变它来工作
#include <iostream>
#include <cstring>
int
main()
char name[] = "SAMPLE TEXT";
std::memset(name, '*', 6);
std::cout << name << '\n';
return 0;
=>
$ g++ -std=c++11 -Wall -Werror test.cc
$ ./a.out
****** TEXT
修复该错误的更改是从char *name
到char name[]
;我也改变了其他一些东西,但只是为了展示更好的风格。这样做是强制编译器在进入main
时将字符串文字复制到可写 内存。 为什么在这里解释需要很长时间;参考一本好的 C++ 教科书。
【讨论】:
【参考方案2】:自 2011 年以来,这不是有效的 C++ 代码,并且以前有过 UB。它是 C 中的 UB。
C++≥11:您不能将字符串文字分配给非const
char
指针。
C++≥98 和 C:不能覆盖字符串文字。
把你的代码改成
char name[] = "SAMPLE TEXT";
您将拥有一个可以被覆盖的本地数组。
【讨论】:
【参考方案3】:代码尝试修改字符串文字 ("SAMPLE TEXT"
) 的内容。这是不允许的。
【讨论】:
以上是关于memset 不使用指向字符的指针的主要内容,如果未能解决你的问题,请参考以下文章