2017-09-23 102 views
0

我刚刚开始使用C++进行编程,并且发现了一个尴尬的问题。基本上:C++类成员充当本地变量

  • 我有一个类的成员是一个char[MAX_LEN]包含文件的完整路径。
  • 我有一个(char*)指向文件的名称(没有完整路径)。

当我构造这个类时,我发现(char*)指针实际上指向构造函数内的局部变量,从而获得错误的结果。

准确地说,类是:

class File_t{ 
    public: 
    char  fullPath[1024]; 
    char*   name; 

File_t(){}; // Default constructor 
File_t(const char* fullPath_){ 
    /* Copy the input name on fullPath */ 
    strncpy(fullPath, fullPath_, sizeof(fullPath)); 

    /* Auxiliary variable to remove the path */ 
    char* auxstr=fullPath; 
    name = auxstr; 

    /* Loop to remove the path */ 
    while(1){ 
     auxstr = strstr(auxstr,"/"); 
     if(auxstr){auxstr=auxstr+1; name=auxstr;} 
     else{break;} 
    } 
} 
}; 

并且,例如,主要在于创造“File_t”的几个实例,并与几个文件填充/一些/路径/ foo1,2,...

int main(int argc, char* argv[]){ 

    const int N = 3; 
    File_t CC[N]; 
    char fileName[100]; 

    for (int i = 0; i < N; i++){ 
    sprintf(fileName,"%s%d","some/path/foo",i); 
    CC[i] = File_t(&fileName[0]); 
    } 


    cout << "Summary" << endl; 
    for (int i=0; i<N; i++) cout << "File " << CC[i].name << " in " << CC[i].fullPath << endl; 


    return 0; 
} 

程序输出是:

File foo2 in some/path/foo0 
File foo2 in some/path/foo1 
File foo2 in some/path/foo2 

也就是说,名点,一些局部变量构造函数。我在Apple,GNU和Intel编译器中遇到了这个问题。 PS:我知道我应该避免在C++中使用C风格的字符串,但这只是为了学习C++基础知识。

+1

切勿使用'strncpy'。 – melpomene

+0

感谢您的评论。我试过strcpy,问题依然存在。感谢您的回答! –

+0

而不是使用'strstr()',使用'strrchr()' - 找出一个字符(而不是一个字符的字符串)的最右边。请注意,您可能需要担心带有尾部斜线('strrchr()'或'strstr()')的'“/ abc/def/ghi //”'。不过,总的来说,你似乎发现人们推荐C++中不使用C风格字符串的原因之一。他们很容易被滥用。 –

回答

5

代码中的问题是一个中断的赋值运算符(和复制构造函数)。在这一行:

CC[i] = File_t(&fileName[0]); 

你构建一个临时File_t对象,然后将其分配给CC[i]fullPath是一个数组,因此所有元素都被复制。这可以。但name是一个指针,所以唯一被复制的是指针本身。这是一个问题,因为它仍然指向临时对象的fullPath

在本声明结束时,临时对象被销毁。现在CC[i].name是一个无效的指针。

要解决这个问题,请定义一个适当的赋值运算符。它可能会这样做:

strcpy(fullPath, other.fullPath); 
name = fullPath + (other.name - other.fullPath); 
+0

你是对的!谢谢! –

0

Melpomene有答案。没有指出复制过程,指针指向局部变量。

如果添加复制过程(以下他的建议):

File_t& operator=(const File_t& other) 
{ 
    strcpy(fullPath, other.fullPath); 
    name = &fullPath[0] + (other.name - &other.fullPath[0]); 
    return *this; 
} 

然后程序工作。

谢谢大家的答案!