public char * 类/结构的成员不可访问?!?!?!po
要遵循的代码片段。
我有一个结构(示例代码有类,尝试了两者,效果相同),它将存储多个 char *。我为该类创建了一个构造函数,将其中大部分初始化为 = ""; 在尝试修改该类实例的该成员时,strncpy 等都报告访问被拒绝。当我在内部结构/类成员函数的范围内使用这些函数时,这些函数甚至报告访问被拒绝。
我的假设是,结构/类的 char * 成员没什么大不了的,也没什么特别的(除了作为一个指向 char 的指针,这要求它在使用之前的某个时刻进行初始化,并在某些时候销毁) )。
如果有人能告诉我我的假设哪里错了,并指导我查阅一些可以澄清正在发生的事情的文献,我将不胜感激。我目前正在vs2008完整版下编译代码。
我预计运行此代码的人会收到有关被拒绝访问某个内存位置的运行时错误。
我还期望当我制作 char * mystr 时,当我稍后说 mystr = ""; 时内存已初始化,以便随后使用 mystr。
我也想认为我不是白痴,但是当我尝试使用本地窗口来确定某个变量的精确内存地址时,我似乎无法让IDE告诉我内存在哪里是在。我必须在记忆窗口里碰运气。那好吧。
帮助!提前致谢。我讨厌和这些愚蠢的 char * 打交道,因为我总是以某种方式把它们弄乱,而且我对它们如何工作的假设是有缺陷的。我想改变这一点,以便我像工具一样命令它们,而不是让它们让我感到沮丧。
再次感谢您的考虑。 Josh
#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 = Something 是不是不同,后者是地址不能更改的指针,而前者是指向不能更改的内存的指针?)。不管怎样,这解释了我收到的错误消息。谢谢大家。
Code snippet to follow.
I have a struct (example code has class, tried both, same effect) that will store a number of char *. I made a constructor for the class that initializes most of them to = "";
Upon attempting to modify that member of an instance of the class, strncpy et all report access denied. These functions even report access denied when i use them in the scope of internal struct/class member functions.
Its been my assumption that having a char * member of a struct/class was no big deal and nothing special (apart from being a pointer to a char, which required that it be initialized at some point before being used, and destroyed at certain times).
I appreciate it if someone could tell me where my assumptions have been wrong, and direct me to some literature that would clarify whats going on. I am currently compiling the code under vs2008 full edition.
I expect that someone who will run this code will get a runtime error about being denied access to a certain memory location.
I also expect that when I make a char * mystr that when I later say mystr = ""; that the memory is initialized for mystr to then be used.
I'd also like to think i'm not an idiot, but when I try to use the locals window to determine the precise in memory address of a certain variable, I can't seem to get the ide to tell me where the memory is at. I ahve to get lucky in the memory window. oh well.
help! Thanks in advance. I hate dealing with these stupid char * cuz I always mess them up somehow, and my assumptions about how they work are flawwed. I want to change this so that I command them like the tools they are, not them frustrate me.
Thanks again for your consideration.
Josh
#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;
}
Response to all: Ok, I've learned that when you assign a string literal to a char * that you're really saying char * const B = "something". (isn't that different from const char * B = something, where the latter is a a pointer whose address can not change, as opposed to the former which is a pointer to memory that can't be changed?). Either way, this explains the error message that I got. Thank you all for that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先将
new
返回的指针分配给B
,然后将指向字符串文字""
的指针分配给B
code>,有效地覆盖了new
返回的指针。正如 Jonathan Leffler 所解释的,字符串文字是只读,因此当您尝试写入
B
指向的字符串文字 (""
) 时,会遇到错误。如果要将空字符串存储在
B
中,则需要使用strcpy()
等库函数(或者最好使用更安全的函数,例如snprintf( )
)。在这种情况下,您也可以将\0
分配给B[0]
,因为这是同样的事情。在 C 和 C++ 中,不能使用=
分配数组(或 C 字符串,它们只是字符数组)。理想情况下,您应该只使用 std::string 而不是原始 C 字符串;那么你就不用担心这类事情了。
You first assign the pointer returned by
new
toB
, then you assign a pointer to the string literal""
toB
, effectively overwriting the pointer returned bynew
.As Jonathan Leffler explains, string literals are read-only, so you encounter an error when you try to write to the string literal (
""
) pointed-to byB
.If you want to store the empty string in
B
, you need to use a library function likestrcpy()
(or preferably, a safer function, likesnprintf()
). In this case, you could also just assign\0
toB[0]
, since that's the same thing. In C and C++, you can't assign arrays (or C strings, which are just arrays of characters) using=
.Ideally, you should just use
std::string
instead of raw C strings; then you don't have to worry about this sort of thing.问题是,当您尝试执行以下操作时:
您正在复制只读数据 - 这不是一个好主意。这是因为指针 C 指向一个字符串文字;不允许覆盖字符串文字。类似的评论适用于 B - 但在那里你也会泄漏内存。
关键点是您对“运行时”而不是“编译时”错误的评论。并不是会员无法访问;而是会员无法访问。当你像你一样初始化它时,它就不会被滥用。
The problem is that when you tried to do:
you are copying over readonly data - which is not a good idea. That's because the pointer, C, points to a string literal; overwriting string literals is not allowed. Similar comments apply to B - but there you are also leaking memory.
The key point is the comment you made about 'run time' not 'compile time' error. It is not that the member is inaccessible; it is just not abusable when you've initialized it as you have.
错误出现
在 mystruct 的构造函数中的行:中。
"test"
是一个指向只读内存的指针,用它来初始化非常量指针是不安全的。编译器不强制执行这一点的唯一原因是在人们关心 const 正确性之前创建了大量 C 代码,这些代码应该被声明为 const,但事实并非如此。同样不是类型安全的。
The error is in the line:
in mystruct's constructor.
"test"
is a pointer to read-only memory, it's not safe to use it to initialize a non-const pointer. The only reason the compiler doesn't enforce this is the huge amount of C code created before people cared about const-correctness, which ought to be declaredconst
but aren't.is likewise not type-safe.