代码之家  ›  专栏  ›  技术社区  ›  Roger Far

c++在编写公共变量时崩溃

c++
  •  0
  • Roger Far  · 技术社区  · 14 年前

    s[i] = s[i] - 'a' + 'A';
    

    例外情况:访问冲突写入位置0x01327808

    #include "stdafx.h"
    #include <iostream>
    
    using namespace std;
    
    class String
    {
    public:
      char *s;
      int len();
      void upper();
    
      String(char*);
    
    };
    
    String::String(char*x)
    {
      s = x;
    }
    
    int String::len()
    {
      return strlen(s);
    }
    
    void String::upper()
    {
      for (int i = 0; i < len(); i++)
      {
        if (s[i] >= 'a' && s[i] <= 'z')
        {
          cout << s[i] << endl;
          s[i] = s[i] - 'a' + 'A';
        }
      }
    };
    
    int main()
    {
      String s("test");
      s.upper();
    
      cout << s.len() << endl;
      cout << s.s << endl;
    
      system("pause");
    }
    
    6 回复  |  直到 14 年前
        1
  •  10
  •   paxdiablo    14 年前

    因为:

    String s("test");
    

    这是为了通过 const char * "test"

    稍后,当您试图修改指针指向的内存时,这是未定义的行为。

    通常,字符串文本将存储在只读内存中以允许进行某些优化,任何修改它们的尝试都将导致访问冲突。

    字符串s(“test”);
    

    char cp[] = "test";
    String s(cp);
    

    你很可能会发现它会起作用的。

    然而,你的班级真的应该 为了字符串本身的目的-仅仅一个指针是不安全的,因为传递给您该指针的代码也可以更改它的内容。

    为了更安全,您应该更改代码:

    • s
    • 您的构造函数应创建自己的字符串副本:
      s = new char[strlen(x)+1];
      strcpy (s,x); .

    • String::~String() { delete[] s; } .
    • 考虑让构造器接收 常量字符* (既然你是 改变它)。
    • 考虑使用 toupper(ch) 而不是 ch - 'a' + 'A' . 虽然你的公式适用于ASCII,但我不相信它有标准的保证。
    • cout s公司
    • 考虑使用无参数构造函数,这样字符串数组就可以正常工作。
        2
  •  2
  •   Matteo Italia    14 年前

    字符串文本是常量(利用不推荐的自动转换 char *

    在实践中,访问冲突发生是因为新版本的VC++将字符串文本放在可执行文件的一部分中,该部分在内存中被映射为只读(这无疑是一件好事),并且试图写入它的任何结果(正确地)都在访问冲突中。

    解决方案 复制 传递给构造函数的字符串(顺便说一句,它应该接受 const char * free 如果你创建了一个字符串对象的副本。

    :在实际的项目中,不要重新发明轮子,使用一个好的预先制作的字符串类,比如 std::string / CString wxString /不管你用的是什么框架。

        3
  •  2
  •   paxdiablo    14 年前
    String::String(char*x) 
    { 
      s = x; 
    } 
    

    不应该像上面那样复制字符串文本地址。行为未定义。

    size_t len = strlen(x);
    s = new char[len+1];
    strcpy(s,x);
    

    确保在String类的析构函数中删除它。

        4
  •  1
  •   Puppy    14 年前

    您试图指定给字符串文字。它们不是char*,而是const char*。试图修改字符串文本是未定义的行为。

        5
  •  0
  •   escargot agile    14 年前

    “test”是常量字符串,不能写入。 s=x; 尝试执行strcpy,这样s将拥有x的非常量副本,而不是常量原件。

        6
  •  0
  •   pyCoder    14 年前

    不能通过使用[]访问来修改“test”字符串。

    错误是s[i]=什么。

    在构造函数中,必须在内部为句柄“test”字符串文本分配空间,然后可以使用[]运算符修改单字符访问。

    要解决的示例(使用基本复制):

    String::String(char *original)
    {
       size_t len = strlen(original) + 1;
       s = new char[len];
    
       for ( size_t i = 0; i < len; ++i )
       {
         s[i] = original[i];
       }
    }