memset无法使用指向字符的指针 [英] memset is not working with pointer to character

查看:167
本文介绍了memset无法使用指向字符的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码有什么问题? memset应该与Pointer一起工作以填充内存块.但是这段代码在控制台中显示了说分段错误(核心已转储)的问题

What is wrong with the following code? memset is supposed to work with Pointer to the block of memory to fill. But this code displays problem in console saying segmentation fault(core dumped)

#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;
}

推荐答案

您已经绊倒了C ++中一个非常老的向后兼容疣,它继承自C,并且可以追溯到没有的日子. const之类的东西.字符串文字的类型为const char [n],但是,除非您告诉编译器不需要与1990年前的代码兼容,否则它会静默地允许您设置char *变量以指向它们.但是它不会允许您通过这样的指针进行编写.实际内存(在可能的情况下)标记为只读;您观察到的分段错误"错误是操作系统如何报告尝试写入只读存储器的尝试.

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.

就语言规范而言,通过非const指针写入const数据-但是您设法将其设置为-具有未定义的行为",这是一种说法程序是错误,但是编译器不必发出诊断信息,并且如果您获得了编译的可执行文件,它可能会执行任何操作." 分段错误"几乎总是意味着您的程序在某处具有未定义的行为.

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

直到您获得足够的技能来知道何时更适合使用不同的设置之前,请使用-std=gnu++11 -Wall -Werror编译C ++程序 all ,或使用与之等效的任何编译器. (您似乎使用的是Unix风格的操作系统,因此这些设置应该可以使用.您可能还需要-g和/或-O.)

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

修正该错误的更改是从char *namechar name[];我也更改了其他几项,但只是为了展示更好的样式.这样做是迫使编译器在输入main时将字符串文字复制到可写内存中. 为什么这样做会花费很长时间来解释.查阅一本好的C ++教科书.

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.

这篇关于memset无法使用指向字符的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆