Доступ к символу * через указатель

вот моя проблема.

У меня есть класс, который регулярно модифицирует символ *.

Есть еще один класс, который должен уметь читать это значение. Поэтому я хочу передать char * в конструктор этого второго класса, чтобы он мог проверить значение, когда это необходимо.

Позвольте мне привести пример реализации, которую я имею для другого параметра, он имеет тип boolean:

В классе А:

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

Пока все хорошо — это похоже на работу. Оба класса могут изменить и получить доступ к этому логическому значению.

Теперь мне нужно сделать то же самое с символом * (я не могу использовать строку, поэтому я думаю, что это лучший способ сохранить короткий текст, например, URL-адрес?).

Итак, вот что я написал:

ClassA:

const char* f_url = "blah blah"; // global

m_eventCatcher.addProxy(porting::shared_ptr<CallbackProxy>(new handleCall2(&f_url)));

ClassC:

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

Я думаю, проблема в том, что строка изменилась, ее адрес тоже изменился? Я действительно запутался — может кто-нибудь сказать мне, что происходит, и что я должен делать в этой ситуации?

ОБНОВИТЬ:

Похоже, проблема в том, КАК я изменяю char *:

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" :(

Есть ли другой способ записать значение строки в символ *?

0

Решение

Я не вижу никаких проблем с доступом к 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();

}
0

Другие решения

Если у вас есть что-то вроде этого:

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();
}

тогда проблема в том, что f_url выходит из области видимости, когда addHandler возвращается.
Если это так, то ваша версия bool также имела проблему, и (*m_dataValid) = false; перезаписал некоторые другие данные.

0

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);
}
};
0

const char* f_url = "blah blah"; // global

Может быть, вы неправильно понимаете эту строку?
Спецификатор const — это когда вы размещаете его, ссылаясь на ключевое слово слева от него.
Разрешается принимать это как первое ключевое слово, но потом, И ТОЛЬКО тогда, оно ссылается на свое право;)
Итак, ваша декларация гласит: (const char) * f_url
так что это указатель на const char.
И я предполагаю (я не знаю, как вы изменяете его значение в этом классе), вы получаете это сами, почему изменение значения const char может закончиться выводом мусора, не так ли?
Я предлагаю вам объявить это

char *const f_url = "blah blah";

это

char (* const) f_url

поэтому f_url — это постоянное значение адреса, указывающее на изменяемую область.
Но даже это не имеет особого смысла, потому что «бла-бла» — это адрес области памяти const, поэтому вы не можете изменить
(«бла-бла») [count] = что-нибудь;
тем не мение.

Так что вы должны просто сделать

char *const f_url = ThisIsACharArray[count];

и получить доступ к массиву символов, иначе String о f_url.

Или лучший способ для вас, как я предполагаю, просто не указывать const в объявлении и выделять изменяемую память для себя;)

0

Строка на самом деле не хранится в 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 который обрабатывает управление памятью для вас. (Это самое простое решение!)

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector