memset is not working with pointer to character

烂漫一生 提交于 2019-12-02 13:10:48

You have tripped over a very old backward-compatibility wart in C++, inherited from C and dating to the days when there was no such thing as const. String literals have type const char [n], but, unless you tell your compiler you don't need to be compatible with pre-1990 code, it will silently allow you to set char * variables to point to them. But it won't allow you to write through such a pointer. The actual memory is (whenever possible) marked read-only; the "segmentation fault" error you observe is how the operating system reports an attempt to write to read-only memory.

In terms of the language specification, writing to const data through a non-const pointer — however you managed to set that up — has "undefined behavior", which is a fancy way of saying "the program is incorrect, but the compiler doesn't have to issue a diagnostic, and if you get a compiled executable, it might do anything." A "segmentation fault" almost always means your program has undefined behavior in it somewhere.

If I compile your program with appropriate settings, I do get an error:

$ 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";
                   ^~~~~~~~~~~~~

Until you gain enough skill to know when different settings are more appropriate, compile all your C++ programs with -std=gnu++11 -Wall -Werror, or whatever your compiler's equivalent of that is. (You appear to be using a Unix-flavor operating system, so those settings should work. You may also want -g and/or -O.)

Your program can be made to work by changing it to read

#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

The change that fixes the bug is from char *name to char name[]; I changed several other things as well, but only to demonstrate better style. What this does is force the compiler to copy the string literal to writable memory upon entry to main. Why it does that would take too long to explain here; consult a good C++ textbook.

This isn't valid C++ code since 2011, and had UB ever before. It is UB in C.

C++≥11: You cannot assign string literals to non-const char pointers.

C++≥98 and C: You cannot overwrite string literals.

change your code to

char name[] = "SAMPLE TEXT";

and you'll have a local array that can be overwritten.

The code tries to modify the content of a string literal ("SAMPLE TEXT"). That's not allowed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!