memset无法使用指向字符的指针

问题描述:

以下代码有什么问题? memset应该使用指针指向要填充的内存块。但是这个代码显示在控制台说分割故障问题(核心转储)自2011年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; 
} 

screenshot of the above program catching a segmentation fault

+0

请勿在此发布文字图片。发布文字。 – EJP

这不是有效的C++代码,和之前曾经有过UB。它是C中的UB。

C++≥11:不能将字符串文字指定给非constchar指针。

C++≥98和C:您不能覆盖字符串文字。

更改您的代码

char name[] = "SAMPLE TEXT"; 

,你就会有一个本地阵列可以被覆盖。

该代码尝试修改字符串文字("SAMPLE TEXT")的内容。这是不允许的。

你已经绊倒了一个非常古老的向后兼容疣的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"; 
        ^~~~~~~~~~~~~ 

,编译所有你的C++程序与-std=gnu++11 -Wall -Werror,或者不管你的编译器是什么。 (你似乎是使用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 *namechar name[]的变化;我改变了其他一些东西,但只是为了展现更好的风格。这样做会迫使编译器在输入main时将字符串文字复制到可写内存。 为什么这样做会花费很长时间来解释;请教一个好的C++教科书。