为什么我的 char* 在弹出一个 char 后不收缩

Why isn't my char* shrinking after popping a char

对于上下文,我正在用 C++ 重写 string class 以用于微控制器,特别是 Arduino,这样它就不会使用 Arduino 不支持的标准库函数。

我在这里查看了几个显示如何从 char* 中弹出字符的答案。但是,在我的函数中,它似乎没有正确编辑 char*.

我的字符串class

#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] != '[=10=]'; 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] = '[=10=]';
                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   %s\n", x.length(), x.str());
    for (int i = 0; i < 5; i++) {
        char res = x.pop_back();
        printf("%d %c %s\n", x.length(), res, x.str());
    }
    //printf("%s\n", 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

其中输出的格式类似于“(长度)(弹出的字符)(结果字符串)”。为什么在调用 pop_back 函数时数据成员 data 没有被改变?

Why isn't the data member data being altered when calling the pop_back function?

即使代码编译(它不应该编译,因为你试图用 字符串文字 构造 x,这是一个 const char[] 无法分配给 non-const char*) 的数组,x 会将其 data 成员指向字符串文字,因此 data[_length] = '[=16=]'; 位于 pop_back() 会调用 未定义的行为 试图改变 read-only 内存。

要使您的代码正常工作,您必须复制 输入数据,例如:

#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] != '[=10=]'; ++i) {
                    data[i] = str[i];
                    ++_length;
                }
                data[_length] = '[=10=]';
            }

           ...
           void clear(void)         { _length = 0; }
           ... 
    };
}