无法使用字符串作为类属性(请参阅更新 4)

发布于 2025-01-17 08:03:50 字数 9870 浏览 5 评论 0原文

以此类为例:

#include <string>
using namespace std;

class One {
private:
  string * text;
public:
  One();
  ~One();

  void setText(string value);

  string uppercase();
  string lowercase();
  string inverted();
};

其实现:

#include "libone.h"

One::One() {
  text = new string();
}

One::~One() {
  delete text;
}

void One::setText(string value) {
  //
}

string One::uppercase() {
  string result(*this->text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result;
}

string One::lowercase() {
  string result(*this->text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result;
}

string One::inverted() {
  string result;

  string temp(*this->text);
  for(int i=temp.size(); i>0; i--) {
    result = result + temp.at(i);
  }

  return result;
}

此处使用:

#include <libone.h>

int main(int argc, char *argv[]) {
  One one;
  one.setText("Kleber Mota de Oliveira");
  cout << "text:" << one.uppercase() << endl;
  cout << "text:" << one.lowercase() << endl;
  return 1;
}

programa 编译时没有错误或警告,但是当我尝试运行可执行文件时,出现分段错误。

我也尝试使用 string text 作为属性,但发生了同样的问题。

我的另一个项目也发生了类似的情况。任何人都可以告诉我我在这里做错了什么?

libone.cpp 的 Makefile

all: libone

libone: ${obj_dir}/libone.o
    g++ -shared -o ${release_dir}/libone.so ${obj_dir}/libone.o -Wl,--out-implib,${release_dir}/libone.a

${obj_dir}/libone.o: src/libone.cpp
    g++ -fPIC -c src/libone.cpp -o ${obj_dir}/libone.o

Main.cpp 的 Makefile

all: main

main: ${obj_dir}/Main.o
    g++ -L ${release_dir} -o ${release_dir}/project -Wl,-rpath='./' ${obj_dir}/Main.o -lone -ltwo

${obj_dir}/Main.o: Main.cpp
    g++ -I ${lib_one_header} -I ${lib_two_header} -c Main.cpp -o ${obj_dir}/Main.o

Makefile

export base_dir := ${CURDIR}
export obj_dir := ${base_dir}/build
export release_dir := ${base_dir}/release

export main_src := ${base_dir}/src
export lib_one_header := ${base_dir}/src/libone/include
export lib_one_src := ${base_dir}/src/libone
export lib_two_header := ${base_dir}/src/libtwo/include
export lib_two_src := ${base_dir}/src/libtwo

lib_one := ${lib_one_src}
lib_two := ${lib_two_src}
libraries := $(lib_one) $(lib_two)
player    := ${main_src}

.PHONY: all $(player) $(libraries)
all: $(player)

$(player) $(libraries): | ${obj_dir} ${release_dir}
    $(MAKE) --directory=$@

$(player): $(libraries)

更新 1

如果我尝试构建 libone. cppMain.cpp 一起:

g++ libone.cpp Main.cpp -o main

仅生成一个可执行文件,一切正常。但是,如果我使用 Makefile 进行构建,以获得单独的库和可执行文件,那么我会收到此分段错误错误。

UPDATE 2

gdb shell 中 backtrace 命令的

#0  0x00007ffff7bd84ec in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6
#1  0x00007ffff7ea6296 in std::char_traits<char>::copy (__n=23, __s2=<optimized out>, __s1=<optimized out>)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/char_traits.h:409
#2  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy (__n=23, __s=<optimized out>, __d=<optimized out>)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:359
#3  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy (__n=23, __s=<optimized out>, __d=<optimized out>)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:354
#4  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign (this=this@entry=0x7fffffffd9ce, __str="Kleber Mota de Oliveira")
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:272
#5  0x00007ffff7ea662f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__str=..., this=0x7fffffffd9ce)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1355
#6  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (this=0x7fffffffd9ce, __str=...)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:680
#7  0x00007ffff7fba255 in One::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from ./libone.so
#8  0x000055555555637d in main ()

结果(使用 string text 作为属性:(使用 string * text 作为属性):

#0  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign (this=this@entry=0x55555556bee0beb0, __str="Kleber Mota de Oliveira")
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:260
#1  0x00007ffff7ea662f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__str=..., this=0x55555556bee0beb0)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1355
#2  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (this=0x55555556bee0beb0, __str=...)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:680
#3  0x00007ffff7fba2a6 in One::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from ./libone.so
#4  0x000055555555637d in main ()

UPDATE 3

通过此更新,仅执行 Main.cpp 中的第一个方法,在第二个方法中,我收到了分段错误错误:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(char* value);

  string uppercase();
  string lowercase();
  string inverted();
};

实现:

void One::setText(char* value) {
  text = value;
}

string One::uppercase() {
  string result = text;

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result;
}

string One::lowercase() {
  string result(text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result;
}

string One::inverted() {
  string result;

  string temp(text);
  for(int i=temp.size()-1; i>=0; i--) {
    result = result + temp[i];
  }

  return result;
}

UPDATE 4

。代码下面,Main.cpp 中调用的所有方法都被执行,但在屏幕上显示一堆垃圾。 示例:

text:�Q���
text:�Q���
text:���t

类声明:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(char* value);

  const char * uppercase();
  const char * lowercase();
  const char * inverted();
};

实现:

const char * One::uppercase() {
  string result = text;

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result.c_str();
}

const char * One::lowercase() {
  string result(text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result.c_str();
}

const char * One::inverted() {
  string result;

  string temp(text);
  for(int i=temp.size()-1; i>=0; i--) {
    result = result + temp[i];
  }

  return result.c_str();
}

UPDATE 5

类声明:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(const char * value);

  const char * uppercase();
  const char * lowercase();
  const char * inverted();
};

实现。 :

#include "libone.h"

#include <iostream>
using namespace std;

One::One() {
  text = new char[1];
  text[0] = '\0';
}

One::~One() {
  delete [] text;
}

void One::setText(const char * value) {
  delete [] text;

  int size = 0;
  for(; value[size] != '\0'; size++);

  text = new char[size];
  for(int i=0; i<size; i++)
    text[i] = value[i];
}

const char * One::uppercase() {
  char * result;

  int size = 0;
  for(; text[size] != '\0'; size++);

  result = new char[size];
  for(int i=0; i<size; i++) {
    if (text[i] >= 65 && text[i] <= 90)
      result[i] = text[i] - 32;
    else
      result[i] = text[i];
  }

  return result;
}

const char * One::lowercase() {
  char * result;

  int size = 0;
  for(; text[size] != '\0'; size++);

  result = new char[size];
  for(int i=0; i<size; i++) {
    if (text[i] >= 33 && text[i] <= 58)
      result[i] = text[i] + 32;
    else
      result[i] = text[i];
  }

  return result;
}

const char * One::inverted() {
  char * result;

  int size = 0;
  for(; text[size] != '\0'; size++)

  result = new char[size];
  for(int i=0; i<size; i++) {
    result[i] = text[size-(i+1)];
  }
  result[size] = '\0';

  return result;
}

Main.cpp

#include "libone.h"

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
  One one;
  one.setText(argv[1]);

  cout << one.uppercase() << endl;
  cout << one.lowercase() << endl;
  cout << one.inverted() << endl;

  return 1;
}

输出:

+leber -ota de /liveira
Kleber Mota de Oliveira
arievilO ed atoM rebelK
*** stack smashing detected ***: terminated
zsh: IOT instruction (core dumped)

Take this class as example:

#include <string>
using namespace std;

class One {
private:
  string * text;
public:
  One();
  ~One();

  void setText(string value);

  string uppercase();
  string lowercase();
  string inverted();
};

its implementation:

#include "libone.h"

One::One() {
  text = new string();
}

One::~One() {
  delete text;
}

void One::setText(string value) {
  //
}

string One::uppercase() {
  string result(*this->text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result;
}

string One::lowercase() {
  string result(*this->text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result;
}

string One::inverted() {
  string result;

  string temp(*this->text);
  for(int i=temp.size(); i>0; i--) {
    result = result + temp.at(i);
  }

  return result;
}

used here:

#include <libone.h>

int main(int argc, char *argv[]) {
  One one;
  one.setText("Kleber Mota de Oliveira");
  cout << "text:" << one.uppercase() << endl;
  cout << "text:" << one.lowercase() << endl;
  return 1;
}

programa compile without errors or warnings, but when I try to run the executable, I got an segmentation fault.

I tried use string text as atribute too, but the same problem happens.

Something similar is happening with another project mine. Anyone can tell me what I am doing wrong here?

Makefile for libone.cpp

all: libone

libone: ${obj_dir}/libone.o
    g++ -shared -o ${release_dir}/libone.so ${obj_dir}/libone.o -Wl,--out-implib,${release_dir}/libone.a

${obj_dir}/libone.o: src/libone.cpp
    g++ -fPIC -c src/libone.cpp -o ${obj_dir}/libone.o

Makefile for Main.cpp

all: main

main: ${obj_dir}/Main.o
    g++ -L ${release_dir} -o ${release_dir}/project -Wl,-rpath='./' ${obj_dir}/Main.o -lone -ltwo

${obj_dir}/Main.o: Main.cpp
    g++ -I ${lib_one_header} -I ${lib_two_header} -c Main.cpp -o ${obj_dir}/Main.o

Makefile

export base_dir := ${CURDIR}
export obj_dir := ${base_dir}/build
export release_dir := ${base_dir}/release

export main_src := ${base_dir}/src
export lib_one_header := ${base_dir}/src/libone/include
export lib_one_src := ${base_dir}/src/libone
export lib_two_header := ${base_dir}/src/libtwo/include
export lib_two_src := ${base_dir}/src/libtwo

lib_one := ${lib_one_src}
lib_two := ${lib_two_src}
libraries := $(lib_one) $(lib_two)
player    := ${main_src}

.PHONY: all $(player) $(libraries)
all: $(player)

$(player) $(libraries): | ${obj_dir} ${release_dir}
    $(MAKE) --directory=$@

$(player): $(libraries)

UPDATE 1

If I try build libone.cpp and Main.cpp together with:

g++ libone.cpp Main.cpp -o main

generating only one executable, everything works fine. But if I build with the Makefiles, to get separate library and executable, then I got this Segmentation fault error.

UPDATE 2

result of the backtrace command in gdb shell (using string text as atribute:

#0  0x00007ffff7bd84ec in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6
#1  0x00007ffff7ea6296 in std::char_traits<char>::copy (__n=23, __s2=<optimized out>, __s1=<optimized out>)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/char_traits.h:409
#2  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy (__n=23, __s=<optimized out>, __d=<optimized out>)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:359
#3  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_copy (__n=23, __s=<optimized out>, __d=<optimized out>)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:354
#4  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign (this=this@entry=0x7fffffffd9ce, __str="Kleber Mota de Oliveira")
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:272
#5  0x00007ffff7ea662f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__str=..., this=0x7fffffffd9ce)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1355
#6  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (this=0x7fffffffd9ce, __str=...)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:680
#7  0x00007ffff7fba255 in One::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from ./libone.so
#8  0x000055555555637d in main ()

(using string * text as atribute):

#0  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign (this=this@entry=0x55555556bee0beb0, __str="Kleber Mota de Oliveira")
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:260
#1  0x00007ffff7ea662f in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign (__str=..., this=0x55555556bee0beb0)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:1355
#2  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator= (this=0x55555556bee0beb0, __str=...)
    at /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:680
#3  0x00007ffff7fba2a6 in One::setText(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) () from ./libone.so
#4  0x000055555555637d in main ()

UPDATE 3

With this update, only the first method in Main.cpp is executed. In the second I got a Segmentation fault error:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(char* value);

  string uppercase();
  string lowercase();
  string inverted();
};

implementation:

void One::setText(char* value) {
  text = value;
}

string One::uppercase() {
  string result = text;

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result;
}

string One::lowercase() {
  string result(text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result;
}

string One::inverted() {
  string result;

  string temp(text);
  for(int i=temp.size()-1; i>=0; i--) {
    result = result + temp[i];
  }

  return result;
}

UPDATE 4

with the code below, all methods called in Main.cpp are executed, but display a bunch of rubish in the screen. An example:

text:�Q���
text:�Q���
text:���t

class declaration:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(char* value);

  const char * uppercase();
  const char * lowercase();
  const char * inverted();
};

implementation:

const char * One::uppercase() {
  string result = text;

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result.c_str();
}

const char * One::lowercase() {
  string result(text);

  for(int i=0; i<result.size(); i++) {
    char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result.c_str();
}

const char * One::inverted() {
  string result;

  string temp(text);
  for(int i=temp.size()-1; i>=0; i--) {
    result = result + temp[i];
  }

  return result.c_str();
}

UPDATE 5

class declaration:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(const char * value);

  const char * uppercase();
  const char * lowercase();
  const char * inverted();
};

implementation:

#include "libone.h"

#include <iostream>
using namespace std;

One::One() {
  text = new char[1];
  text[0] = '\0';
}

One::~One() {
  delete [] text;
}

void One::setText(const char * value) {
  delete [] text;

  int size = 0;
  for(; value[size] != '\0'; size++);

  text = new char[size];
  for(int i=0; i<size; i++)
    text[i] = value[i];
}

const char * One::uppercase() {
  char * result;

  int size = 0;
  for(; text[size] != '\0'; size++);

  result = new char[size];
  for(int i=0; i<size; i++) {
    if (text[i] >= 65 && text[i] <= 90)
      result[i] = text[i] - 32;
    else
      result[i] = text[i];
  }

  return result;
}

const char * One::lowercase() {
  char * result;

  int size = 0;
  for(; text[size] != '\0'; size++);

  result = new char[size];
  for(int i=0; i<size; i++) {
    if (text[i] >= 33 && text[i] <= 58)
      result[i] = text[i] + 32;
    else
      result[i] = text[i];
  }

  return result;
}

const char * One::inverted() {
  char * result;

  int size = 0;
  for(; text[size] != '\0'; size++)

  result = new char[size];
  for(int i=0; i<size; i++) {
    result[i] = text[size-(i+1)];
  }
  result[size] = '\0';

  return result;
}

Main.cpp

#include "libone.h"

#include <iostream>
using namespace std;

int main(int argc, char *argv[]) {
  One one;
  one.setText(argv[1]);

  cout << one.uppercase() << endl;
  cout << one.lowercase() << endl;
  cout << one.inverted() << endl;

  return 1;
}

output:

+leber -ota de /liveira
Kleber Mota de Oliveira
arievilO ed atoM rebelK
*** stack smashing detected ***: terminated
zsh: IOT instruction (core dumped)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不语却知心 2025-01-24 08:03:50

没有充分的理由使 text 成员成为 string* 指针(特别是因为您没有遵循 3/5/0 规则来正确管理指针,但在本练习中我们可以忽略它,因为您没有复制一个 目的)。

但是,为了便于讨论,我们只是说,无论出于何种原因,您都需要一个指针。您的代码犯的唯一错误是:

  • setText() 中,您没有将 value 分配给 text,例如:
void One::setText(string value) {
  *this->text = value;
}
  • inverse 中(),您正在越界访问 temp 字符串,它应该是这样的:
string One::inverted() {
  string result;

  string temp(*this->text);
  for(int i=temp.size()-1; i>=0; i--) {
    result = result + temp[i];
  }

  return result;
}

您显示的其余代码工作正常:

在线演示

更新

您的代码问题在于您正在动态库中实现 One。因此,您无法跨库边界传递非 POD 类型,例如 std::string。因此,尝试更像这样的事情:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(const char *value);

  char* uppercase();
  char* lowercase();
  char* inverted();
};

void freeString(char *str);
#include "libone.h"
#include <cstring>
#include <cctype>
using namespace std;

One::One() {
  text = new char[1];
  *text = '\0';
}

One::~One() {
  delete[] text;
}

void One::setText(const char *value) {
  delete[] text;
  text = new char[strlen(value)+1];
  strcpy(text, value);
}

char* One::uppercase() {
  int len = strlen(text);

  char* result = new char[len+1];
  strcpy(result, text);

  for(int i = 0; i < len; i++) {
    unsigned char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result;
}

char* One::lowercase() {
  int len = strlen(text);

  char *result = new char[len+1];
  strcpy(result, text);

  for(int i = 0; i < len; i++) {
    unsigned char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result;
}

char* One::inverted() {
  int len = strlen(text);

  char *result = new char[len+1];

  for(int i = 0; i < len; i++) {
    result[i] = text[len-1-i];
  }

  return result;
}

void freeString(char *str) {
    delete[] str;
}
#include <libone.h>

int main(int argc, char *argv[]) {
  One one;
  one.setText("Kleber Mota de Oliveira");

  char *str = one.uppercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.lowercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.inverted();
  cout << "text:" << str << endl;
  freeString(str);

  return 1;
}

或者:

class One {
private:
  void * text;
public:
  One();
  ~One();

  void setText(const char *value);

  char* uppercase();
  char* lowercase();
  char* inverted();
};

void freeString(char *str);
#include "libone.h"
#include <string>
using namespace std;

One::One() {
  text = new std::string;
}

One::~One() {
  delete static_cast<std::string*>(text);
}

void One::setText(const char *value) {
  *static_cast<std::string*>(text) = value;
}

char* One::uppercase() {
  std::string temp = *static_cast<std::string*>(text);

  for(size_t i = 0; i < temp.size(); i++) {
    unsigned char c = temp[i];
    c = toupper(c);
    temp[i] = c;
  }

  char* result = new char[temp.size()+1];
  strcpy(result, temp.c_str());
  return result;
}

char* One::lowercase() {
  std::string temp = *static_cast<std::string*>(text);

  for(size_t i = 0; i < temp.size(); i++) {
    unsigned char c = temp[i];
    c = tolower(c);
    temp[i] = c;
  }

  char *result = new char[temp.size()+1];
  strcpy(result, temp.c_str());
  return result;
}

char* One::inverted() {
  std::string &str = *static_cast<std::string*>(text);

  std::string temp;
  temp.reserve(str.size());

  for(size_t i = str.size(); i > 0; i--) {
    temp += str[i-1];
  }

  char *result = new char[temp.size()+1];
  strcpy(result, temp.c_str());
  return result;
}

void freeString(char *str) {
    delete[] str;
}
#include <libone.h>

int main(int argc, char *argv[]) {
  One one;
  one.setText("Kleber Mota de Oliveira");

  char *str = one.uppercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.lowercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.inverted();
  cout << "text:" << str << endl;
  freeString(str);

  return 1;
}

There is no good reason to make the text member be a string* pointer (especially since you are not following the Rule of 3/5/0 to manage the pointer properly, but we can ignore that for this exercise since you are not making any copies of the one object).

But, let's just say, for the sake of argument, that you need a pointer, for whatever reason. The only mistakes your code is making are:

  • in setText(), you are not assigning value to text, eg:
void One::setText(string value) {
  *this->text = value;
}
  • in inverse(), you are accessing the temp string out of bounds, it should be like this instead:
string One::inverted() {
  string result;

  string temp(*this->text);
  for(int i=temp.size()-1; i>=0; i--) {
    result = result + temp[i];
  }

  return result;
}

The rest of the code you have shown works fine:

Online Demo

UPDATE:

The problem with your code is that you are implementing One in a dynamic library. As such, you can't pass non-POD types, like std::string, across the library boundary. So, try something more like this instead:

class One {
private:
  char * text;
public:
  One();
  ~One();

  void setText(const char *value);

  char* uppercase();
  char* lowercase();
  char* inverted();
};

void freeString(char *str);
#include "libone.h"
#include <cstring>
#include <cctype>
using namespace std;

One::One() {
  text = new char[1];
  *text = '\0';
}

One::~One() {
  delete[] text;
}

void One::setText(const char *value) {
  delete[] text;
  text = new char[strlen(value)+1];
  strcpy(text, value);
}

char* One::uppercase() {
  int len = strlen(text);

  char* result = new char[len+1];
  strcpy(result, text);

  for(int i = 0; i < len; i++) {
    unsigned char c = result[i];
    c = toupper(c);
    result[i] = c;
  }

  return result;
}

char* One::lowercase() {
  int len = strlen(text);

  char *result = new char[len+1];
  strcpy(result, text);

  for(int i = 0; i < len; i++) {
    unsigned char c = result[i];
    c = tolower(c);
    result[i] = c;
  }

  return result;
}

char* One::inverted() {
  int len = strlen(text);

  char *result = new char[len+1];

  for(int i = 0; i < len; i++) {
    result[i] = text[len-1-i];
  }

  return result;
}

void freeString(char *str) {
    delete[] str;
}
#include <libone.h>

int main(int argc, char *argv[]) {
  One one;
  one.setText("Kleber Mota de Oliveira");

  char *str = one.uppercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.lowercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.inverted();
  cout << "text:" << str << endl;
  freeString(str);

  return 1;
}

Alternatively:

class One {
private:
  void * text;
public:
  One();
  ~One();

  void setText(const char *value);

  char* uppercase();
  char* lowercase();
  char* inverted();
};

void freeString(char *str);
#include "libone.h"
#include <string>
using namespace std;

One::One() {
  text = new std::string;
}

One::~One() {
  delete static_cast<std::string*>(text);
}

void One::setText(const char *value) {
  *static_cast<std::string*>(text) = value;
}

char* One::uppercase() {
  std::string temp = *static_cast<std::string*>(text);

  for(size_t i = 0; i < temp.size(); i++) {
    unsigned char c = temp[i];
    c = toupper(c);
    temp[i] = c;
  }

  char* result = new char[temp.size()+1];
  strcpy(result, temp.c_str());
  return result;
}

char* One::lowercase() {
  std::string temp = *static_cast<std::string*>(text);

  for(size_t i = 0; i < temp.size(); i++) {
    unsigned char c = temp[i];
    c = tolower(c);
    temp[i] = c;
  }

  char *result = new char[temp.size()+1];
  strcpy(result, temp.c_str());
  return result;
}

char* One::inverted() {
  std::string &str = *static_cast<std::string*>(text);

  std::string temp;
  temp.reserve(str.size());

  for(size_t i = str.size(); i > 0; i--) {
    temp += str[i-1];
  }

  char *result = new char[temp.size()+1];
  strcpy(result, temp.c_str());
  return result;
}

void freeString(char *str) {
    delete[] str;
}
#include <libone.h>

int main(int argc, char *argv[]) {
  One one;
  one.setText("Kleber Mota de Oliveira");

  char *str = one.uppercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.lowercase();
  cout << "text:" << str << endl;
  freeString(str);

  str = one.inverted();
  cout << "text:" << str << endl;
  freeString(str);

  return 1;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文