就上下文而言,我正在重写C++中的string
类,以便在微控制器上使用,特别是在Arduino上,这样它就不会使用Arduino不支持的标准库函数。
我在这里看到了几个答案,它们展示了如何从char*
中弹出一个字符。然而,在我的函数中,它似乎没有正确地编辑char*
。
我的字符串类
#include <stdlib.h> // malloc
namespace micro_std {
class string {
private:
const int MAX_SIZE = 4096; // Maximum size on 16bit controllers.
char* data = nullptr;
int _length = 0;
public:
string(char* data) {
this->data = data;
for (int i = 0; data[i] != ' '; i++)
_length++;
}
int size(void) const { return _length; }
int length(void) const { return _length; }
int max_size(void) const { return MAX_SIZE; }
bool empty(void) const { return _length == 0; }
char at(int index) const { return data[index]; }
char back(void) const { return data[_length - 1]; }
char front(void) const { return data[0]; }
char* str(void) const { return data; }
void clear(void) { _length = 0; data = nullptr; }
// removed for brevity //
char pop_back(void) {
_length--;
char character = data[_length];
data[_length] = ' ';
return character;
}
// removed for brevity //
};
}
以及我如何测试我的代码,特别是pop_back
函数。
#include <stdio.h> // printf
#include "micro_std/string.h"
int main(int argc, char** argv) {
micro_std::string x = "abcdef";
// Testing pop_back function
printf("%d %sn", x.length(), x.str());
for (int i = 0; i < 5; i++) {
char res = x.pop_back();
printf("%d %c %sn", x.length(), res, x.str());
}
//printf("%sn", x.str());
return 0;
}
如果需要的话,我的编译器参数
g++ -w -std=c++2a -O3 program.cpp -o program
运行这个程序会给我以下输出:
6 abcdef
5 f abcdef
4 e abcdef
3 d abcdef
2 c abcdef
1 b abcdef
而不是我想要的输出:
6 abcdef
5 f abcde
4 e abcd
3 d abc
2 c ab
1 b a
在输出被格式化为类似于"0"的情况下;(长度((弹出字符((结果字符串(";。为什么在调用pop_back
函数时没有更改数据成员data
?
为什么在调用pop_back函数时没有更改数据成员数据?
即使代码编译(不应该编译,因为您试图用字符串文字构造x
,这是一个不能分配给非常量char*
的const char[]
数组(,x
也会将其data
成员指向字符串文字,因此pop_back()
内部的data[_length] = ' ';
会调用未定义行为来更改只读内存。
要使您的代码工作,您必须对输入数据进行复制,例如:
#include <stdlib.h> // malloc
namespace micro_std {
class string {
private:
const int MAX_SIZE = 4096; // Maximum size on 16bit controllers.
char _data[MAX_SIZE];
int _length = 0;
public:
string(const char* str) {
for (int i = 0; str[i] != ' '; ++i) {
data[i] = str[i];
++_length;
}
data[_length] = ' ';
}
...
void clear(void) { _length = 0; }
...
};
}