dev에선 잘되고 visual에선 컴파일은 되는데 실행파일 실행시키면 std::bad allo이라고 뜨는데 어떻게 해결해야할까요?

salmon16의 이미지

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class MyString {
        char* str ; 
        int size ; 
    public: 
        MyString( char* _str) :size(strlen(_str)),str(new char[size]){
 
            for( int i = 0; i < size; i++) {
                str[i] = _str[i];
            }
        }
        MyString() {
            str = NULL;
            size = 0;
        }
        MyString(const MyString& another) :size(another.size),
            str(new char[another.size]) {
                for ( int i = 0; i < size; i++) {
                    str[i] = another.str[i];
                }
            }
        void set(char * _str){
            size = strlen(_str);
            str = new char[size];
            for ( int i = 0; i < size; i++) {
                str[i] = _str[i];
            }
        }
        int isEqual(const MyString& target)const { 
 
            if (strcmp(str,target.str) == 0)
                return 1;
            else return 0;
        }
        void print()const {
            for ( int i = 0; i < size;i ++) {
                cout << str[i];
            }
            cout << endl;
        }
        ~MyString() {
            delete  str;
        }
 
} ;
int main() { 
    MyString strs[] = { 
        MyString("C"), 
        MyString(), 
        MyString("Java") 
        } ; 
        strs[1].set("C++") ;
 
    const MyString target("Java") ; 
    for ( int i = 0 ; i < 3 ; i ++ ) { 
        const MyString str(strs[i]) ; 
        if ( str.isEqual(target) ) { 
            cout << "[" << i << "]: " ; 
            str.print() ; 
            break ; 
            } 
    } 
    for ( int i = 0 ; i < 3 ; i ++ ) { 
        const MyString& str = strs[i] ; 
        str.print() ; 
    }
}
이 코드인데 어디서 오류가 발생한걸까요?
익명 사용자의 이미지

해법: size와 str 선언 줄 바꾸기

C++ 초기화가 이런 식인데, 헷갈리면 그냥 생성자 안에서 초기화하세요.

salmon16의 이미지

그것은 바꿀수가 없습니다 ㅜ

salmon16의 이미지

생성자안에선 어떻게 또 초기화하나요?

익명 사용자의 이미지

class MyString {
        char* str ; 
        int size ; 
    public: 
        MyString( char* _str) :size(strlen(_str)),str(new char[size]){
 
            for( int i = 0; i < size; i++) {
                str[i] = _str[i];
            }
        }
    // 후략

생성자의 size(strlen(_str)),str(new char[size]) 부분에서 초기화가 진행되는 순서는 여기서 나열한 순서가 아니라 클래스 내부의 필드 선언 순서입니다.

즉 str이 먼저 초기화되고 그 다음 size가 초기화되는 것이죠.

그런데 str을 초기화할 때 아직 초기화되지 않은 필드 size를 참조하고 있네요? bad alloc이 안 뜰 수가 없습니다.

클래스 내부에서 int size를 먼저 선언하도록 바꾸면 문제가 해결될 겁니다.

salmon16의 이미지

감사합니다

salmon16의 이미지

class MyString {
char* str;
int size;
public:
MyString(const char* _str) {
size = strlen(_str) + 1;
str = new char[size];
if (str)
for (int i = 0; i < size; i++) str[i] = _str[i];
} 이코드는 왜 실행이 되는걸까요?

익명 사용자의 이미지

생성자 body 내부의 statement들은 여느 다른 함수들에서와 마찬가지로 위에서부터 차례로 실행되기 때문이지요.

저는 개인적으로 가능한 한 ctor-initializer를 쓰는 편을 좋아합니다만, 뭐, 보아하니 굉장히 이상한 제약에 묶여 계신 것 같군요.

익명 사용자의 이미지

같은 답을 두 분이 하셨는데 이해하지 못하신 것 같네요.

원래 코드에서 :size(strlen(_str)), str(new char[size]) 순서로 쓰셨는데, 이렇게 쓰셔도 초기화되는 순서는 size 다음에 str이 아니라 str이 먼저 초기화됩니다. 선언된 순서로 str(new char[size])이 먼저 실행된다는 뜻입니다. 모르시면 이상하게 생각하는 건 당연한데 C++ 스펙이 그렇게 생겼어요.

위 코드처럼 생성자 안에서 그렇게 쓰면 쓴 순서대로 초기화되구요.

salmon16의 이미지

감사합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.