要遵循的代码段。
我有一个结构(示例代码有类,试过两个,效果相同),它将存储一些char *。我为类创建了一个构造函数,将其中的大多数初始化为=“”; 在尝试修改该类实例的该成员时,strncpy et all报告访问被拒绝。当我在内部struct / class成员函数的范围内使用它们时,这些函数甚至会报告拒绝访问。
我的假设是,拥有一个struct *类的char *成员并不是什么大问题而且没什么特别的(除了是一个指向char的指针,它要求在使用之前将其初始化,并销毁在某些时候)。
如果有人能告诉我我的假设在哪里出错,我感激不尽,并指导我介绍一些可以澄清最新情况的文献。我目前正在编译vs2008完整版的代码。
我希望运行此代码的人会因拒绝访问某个内存位置而遇到运行时错误。
我还希望当我制作一个char * mystr时,我后来说mystr =“”;为mystr初始化内存然后使用。
我也想我不是白痴,但是当我尝试使用locals窗口来确定某个变量的精确内存地址时,我似乎无法告诉我记忆所在的地方。我想在内存窗口中幸运。哦,好吧。
帮助!提前致谢。我讨厌处理这些愚蠢的char * cuz我总是以某种方式弄乱它们,而且我对它们如何工作的假设是夸张的。我想改变它,以便我像他们的工具那样命令他们,而不是让他们感到沮丧。
再次感谢您的考虑。 约什
#include <stdio.h>
#include <string.h>
class mystruct {
public:
int A;
char* B;
char* C;
mystruct() {
A = 0xFE;
B = new char[32];
B = "";
C = "test";
}
void test(char *input) {
strncpy(B,input, strlen(input));
}
};
int main(char* argv[], int argc) {
mystruct work;
char wtf[32];
// work.A = 0xbb;
work.test("gotchabitch!");
// sprintf(wtf, "address of work is %x" , &work);
// strncpy(work.C,"gotchabitch!\0",strlen("gotchabitch!\0"));
strncpy(work.B,"gotchabitch!",strlen("gotchabitch!"));
printf("%d;%s;%s;", work.A, work.B, work.C);
return 0;
}
对所有人的回应:好的,我已经了解到,当你将字符串文字分配给char *时,你真的在说char * const B =“something”。 (与const char * B =没有什么区别,后者是一个地址不能改变的指针,而前者是一个无法改变的内存指针?)。无论哪种方式,这都解释了我得到的错误消息。谢谢大家。
答案 0 :(得分:1)
B = new char[32];
B = "";
首先将new
返回的指针分配给B
,然后将指向字符串文字""
的指针分配给B
,有效地覆盖new
返回的指针。 {1}}。
As Jonathan Leffler explains,字符串文字是只读的,因此当您尝试写入""
指向的字符串文字(B
)时会遇到错误。
如果要将空字符串存储在B
中,则需要使用类似strcpy()
的库函数(或者最好使用更安全的函数,如snprintf()
)。在这种情况下,您也可以将\0
分配给B[0]
,因为这是相同的事情。在C和C ++中,您不能使用=
分配数组(或C字符串,它们只是字符数组)。
理想情况下,您应该使用std::string
而不是原始C字符串;那么你不必担心这种事情。
答案 1 :(得分:1)
问题在于你试图做的时候:
strncpy(work.C, "something", strlen(something));
你正在复制只读数据 - 这不是一个好主意。那是因为指针C指向字符串文字;不允许覆盖字符串文字。类似的评论适用于B - 但你也在泄漏记忆。
关键是您对“运行时间”而非“编译时间”错误的评论。并不是该成员无法进入;当你按原样初始化它时,它就不会被滥用了。
答案 2 :(得分:1)
错误在于:
C = "test";
在mystruct的构造函数中。 "test"
是指向只读内存的指针,使用它来初始化非const指针是不安全的。编译器没有强制执行此操作的唯一原因是在人们关心const-correctness之前创建了大量的C代码,这些代码应该被声明为const
但不是。
B = "";
同样不是类型安全的。