通过指针访问字符*
Accessing a char* through a pointer
这是我的问题。
我有一个定期修改字符*的类。
还有另一个类,需要能够读取此值。所以我想将 char* 传递给第二个类的构造函数,以便它可以在需要时检查值。
让我举一个我为另一个参数提供的实现示例,它是布尔类型:
在A类中:
bool f_valid = false; // global
m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall(&f_valid)));
在B类中:
struct handleCall
{
bool* m_dataValid;
handleCall(bool* result)
{
// saving the pointer to the boolean that I want to change
m_dataValid = result;
}
method()
{
if (smth)
{
(*m_dataValid) = false;
}
}
};
到目前为止一切顺利 - 这似乎有效。这两个类都可以更改和访问此布尔值。
现在我需要用 char* 做同样的事情(我不能使用字符串,所以我想这是存储短文本的最佳方式,比如 url 地址?
所以这是我写的:
A类:
const char* f_url = "blah blah"; // global
m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall2(&f_url)));
C类:
struct handleCall2
{
char ** m_url;
handleCall2(char** url)
{
// saving the pointer to the char*
m_url= url;
std::cout << (*m_url) << std::endl; // prints out url fine
}
method()
{
std::cout << (*m_url) << std::endl; // by this time the value has been changed by ClassA, and I print out some rubbish - symbols, squares, etc.
}
};
我想问题是因为字符串变了,它的地址也变了?我真的很困惑 - 有人可以告诉我发生了什么,在这种情况下我该怎么办?
更新:
看起来问题出在我如何修改字符*:
f_url = "new text"; // works fine
f_url = fileUrl.c_str(); // doesn't work! I get rubbish in the value when I try to access it from ClassB
strcpy(m_url, fileUrl.c_str()); // I also removed const from the variable and tried this - got a crash "access violation using location" :(
有没有其他方法可以将字符串的值写入字符 *?
我认为访问char *
没有任何问题。
写了一个示例代码,它对我有用。可能是你的是一个不同的问题:
顺便说一句,这是我的代码供您参考:
#include <iostream>
class ClassThatPrints
{
private:
const char **m_url;
public:
ClassThatPrints(const char ** url)
{
m_url = url;
std::cout << (*m_url) << std::endl;
}
void PrintAfterModify(void)
{
std::cout << (*m_url) << std::endl;
}
};
class ClassThatModifies
{
private:
const char *m_charPointer;
ClassThatPrints *m_ClassThatPrints;
public:
ClassThatModifies()
{
m_charPointer = "this is the original string";
std::cout << "Printing before modification:" << std::endl;
m_ClassThatPrints = new ClassThatPrints(&m_charPointer);
}
~ClassThatModifies() {
delete m_ClassThatPrints;
}
void ModifyStringAndPrint(void)
{
m_charPointer = "this is a modified string";
std::cout << "Printing after modification:" << std::endl;
m_ClassThatPrints->PrintAfterModify();
}
};
int main()
{
ClassThatModifies objClassThatModifies;
objClassThatModifies.ModifyStringAndPrint();
}
如果你有这样的东西:
void addHandler() {
const char* f_url = "blah blah";
m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall2(&f_url)));
}
void doStuff() {
addHandler();
m_eventCatcher.callProxy();
}
那么问题是当 addHandler 返回时f_url超出了范围。如果是这种情况,那么您的布尔版本也存在问题,(*m_dataValid) = false;
覆盖了一些其他数据。
const char* f_url = "blah blah";
此声明表示您有一个指向常量字符串的指针。所以你不能做
strcpy(f_url, "hello world"); // copy to the preallocated place
但你可以
f_url = "hello world"; // do pointer assignment
如果您有以下情况:
class ClassA {
const char* f_url = "blah blah";
public:
void method() {
f_url = "hello world";
}
};
class ClassB {
char** m_url;
public:
void print() {
cout << (* m_url); // m_url points to a string, allocated on the stack of ClassA::method()
}
};
请记住,字符串"hello world"
是在ClassA::method()
的堆栈上分配的。当ClassA::method()
退出时,该指针不再有效。为了解决我接下来提出的问题:
class ClassA {
static const int max_path = 256;
char f_url[max_path];
public:
void method() {
strcpy(f_url, "hello world");
}
};
class ClassB {
char** m_url;
public:
void print() {
cout << (* m_url);
}
};
const char* f_url = "blah blah"; // global
也许你误解了这句话?const 限定符是当你放置它时,指的是它左侧的关键字。它被允许将其作为第一个关键字,但只有这样,它才引用其正确的;)所以你的声明说:(常量字符(*f_url所以它是一个指向常量字符的指针。而且我猜(我不知道你在那个类中修改它的值的方式是什么(你自己得到它,为什么修改常量字符值可能会以垃圾输出结束,不是吗?我建议你想把它声明为
char *const f_url = "blah blah";
这是
字符 (* 康斯特( f_url
所以f_url是一个常量地址值,它指向一个可修改的区域。但即使这样也没有多大意义,因为"blah blah"是常量内存区域的地址,所以你不能修改 ("废话"([计数] = 任何内容;无论如何。
所以你应该只做
char *const f_url = ThisIsACharArray[count];
并访问 char 数组又名字符串关于f_url。
或者更好的方法,正如我猜的那样,只需将常量排除在声明之外,并通过您自己的;)分配可修改的内存
字符串实际上并不存储在 f_url
中。字符串存储在其他地方,f_url
是指向其他地方的指针。
如果这样做:
f_url = "new text"; // works fine
编译程序时,它将包含字符串"new text"
其中的某处。 f_url
将指向这一点 - 程序本身中间的一些内存。
f_url = fileUrl.c_str(); // doesn't work! I get rubbish in the value when I try to access it from ClassB
fileUrl
是一个 std::string。 fileUrl
有自己的指向字符串的指针,该字符串c_str返回。由于fileUrl
负责管理此字符串,因此当fileUrl
超出范围时,内存可能会被重用于其他内容 - 它不知道您仍在使用该内存。
// I assume you meant f_url here, not m_url
strcpy(f_url, fileUrl.c_str()); // I also removed const from the variable and tried this - got a crash "access violation using location" :(
这的作用取决于f_url
实际指向什么。如果f_url
指向程序中间的一些内存(与f_url = "blah blah";
一样(,那么这将崩溃。通常,这表示存在错误,因此操作系统将不允许您这样做。
如果允许,可能会发生这种情况:
char *s = "hello world";
strcpy(s, "abracadabra");
printf("hello world"); // prints "abracadabra"
你需要做的是获取自己的内存块来保存字符串,并在完成后释放它:
f_url = new char[fileUrl.length() + 1];
strcpy(f_url, fileUrl.c_str());
// when you don't need the string any more
delete [] f_url;
或:
f_url = strdup(fileUrl.c_str());
// when you don't need the string any more
free(f_url);
或者只是f_url
为您处理内存管理的std::string
。(这是最简单的解决方案!
- 按字符值访问int数组
- 如何循环访问常量字符**?
- 固有构造函数的字符和访问级别
- 在函数 strcpy() 中访问字符数组时出现分段错误
- 如何循环访问 cpp 中的函数返回的字符指针数组
- 为什么没有访问所有字符串字符?
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 当我用"ñ"字符循环访问字符串时出现奇怪的结果
- 循环访问 C++ 个字符数组的位
- 通过C++中的指针访问字符数组
- 在C 字符串中,为什么在最后一个字符之后,通过索引和()访问索引时行为是不同的
- Cout 在循环访问常量字符时提供垃圾输出
- 访问字符阵列中不可用的内存位置(超出范围值)
- 如何在C++中访问带有星号的常量字符*数组
- 如何使用字符串字符数组中的 ++ 运算符访问下一个字符串
- 是否可以超载[]运算符在不定义类的情况下访问特定的字符
- 访问没有字符的字符串的第一个字符
- 如何访问 <int,字符串>映射中的特定字符?
- 访问动态 2D 字符数组时引发访问冲突异常
- 从字符[]访问对齐的T和的最有效方法是什么?