2009-12-04 53 views
-2

- 所有修改後的代碼仍然拒絕運行,請幫助 -在Windows上我沒有在Mac上得到strcpy錯誤?

當我在Windows中編譯我的代碼時,出現內存錯誤。但是,在我最初編碼此代碼的Mac中,它工作正常。我需要在Windows上正常工作。

這與我使用strcpy處理char字符串的方式有關,Mac似乎很好(我想這與gcc和微軟的做事方式有關)。


下面是抱怨者的代碼: 的main.cpp

#include "Cust.h" 
using namespace std; 

int main (int argc, char * const argv[]) { 
    Cust customers[500]; 
    char tmpString[70] = " "; 
    char * pch = new char[255]; 
    string tmpAcctFN = " "; 
    string tmpAcctLN = " "; 
    ifstream input("P3_custData.txt"); 
    for (int idx = 0; idx < 130; idx++){ 
     input.getline(tmpString, 70, '\n'); 
     strcpy(pch,strtok(tmpString," "),255); 
     customers[idx].setAcctNum(pch); 
     cout << pch << endl; 
     strcpy(pch, strtok(NULL," "));; 
     customers[idx].setAcctFN(pch); 
     cout << pch << endl; 
     strcpy(pch, strtok(NULL," "));; 
     customers[idx].setAcctLN(pch); 
     cout << pch << endl; 
     strcpy(pch, strtok(NULL," "));; 
     customers[idx].setCurrBalance(atol(pch)); 
     cout << pch << endl; 
     strcpy(pch, strtok(NULL," "));; 
     customers[idx].setPIN(atoi(pch)); 
     cout << pch << endl; 
    } 
    input.close(); 
    return 0; 
} 

Cust.h

/* 
* Cust.h 
* Project 3 
* 
* Created by Anthony Glyadchenko on 11/17/09. 
* Copyright 2009 __MyCompanyName__. All rights reserved. 
* 
*/ 
#include <iostream> 
#include <string> 

using namespace std; 

#ifndef CUST_H 
#define CUST_H 

class Cust{ 
public: 
    char * getAcctNum(); 
    void setAcctNum(char num[]); 
    double getCurrBalance(); 
    void setCurrBalance(double balance); 
    void addToCurrBalance(double amount); 
    void subFromCurrBalance(double amount); 
    void setAcctFN(char firstName[]); 
    void setAcctLN(char lastName[]); 
    char * getAcctFN(); 
    char * getAcctLN(); 
    void setPIN(int pin); 
    int getPIN(); 

private: 
    char acctNum[255]; 
    char acctFN[255]; 
    char acctLN[255]; 
    double currBalance; 
    int pin; 
    char fileName[255]; 
}; 
#endif 

Cust.cpp

/* 
* Cust.cpp 
* Project 3 
* 
* Created by Anthony Glyadchenko on 11/17/09. 
* Copyright 2009 __MyCompanyName__. All rights reserved. 
* 
*/ 
#include <fstream> 
#include <string> 
#include <sstream> 
#include "Cust.h" 

using namespace std; 

char * Cust::getAcctNum(){ 
    return acctNum; 
} 

void Cust::setAcctNum(char num[]){ 
    strcpy(acctNum,num); 
} 

double Cust::getCurrBalance(){ 
    return currBalance; 
} 

void Cust::setCurrBalance(double balance){ 
    currBalance = balance; 
} 

void Cust::addToCurrBalance(double amount){ 
    currBalance += amount; 
} 

void Cust::subFromCurrBalance(double amount){ 
    currBalance -= amount; 
} 

void Cust::setAcctFN(char firstName[]){ 
    strcpy(acctFN,firstName); 
} 

void Cust::setAcctLN(char lastName[]){ 
    strcpy(acctLN,lastName); 

} 

char * Cust::getAcctFN(){ 
    return acctFN; 
} 

char * Cust::getAcctLN(){ 
    return acctLN; 
} 

void Cust::setPIN(int pin){ 
    Cust::pin = pin; 
} 

int Cust::getPIN(){ 
    return pin; 
} 

這裏是我的堆棧跟蹤:

Index Function 
-------------------------------------------------------------------------------- 
1  msvcr90d.dll!68d7f693() 
2  [Frames below may be incorrect and/or missing, no symbols loaded for msvcr90d.dll] 
*3  P3.exe!main(int argc=0, char * const * argv=0x0036fcd0) 
4  [email protected]() 
5  [email protected]+170(__except_handler4)() 
6  kernel32.dll!75eb3677() 
7  ntdll.dll!77b29d72() 
8  ntdll.dll!77b29d45() 
+4

Downvoted for「go get my zipfile」。一個格式良好的簡短代碼片段可以更有幫助。 – 2009-12-04 18:41:27

+0

好了,有時候有一個可下載的zip也很好。 :) – Dave 2009-12-04 18:51:02

+0

如果有人想要zip(它也有txt文件),請在這裏留言。 – 2009-12-04 18:52:40

回答

4

有幾件事情要檢查(抱歉不會下載代碼):

  1. 沒有G ++的* .c有警告?如果這樣修復它們。
  2. 確實g ++ -W有警告?如果這樣修復它們。
  3. 確實g ++ -W -Wall有警告?如果這樣修復它們。
  4. 確實g ++ -W -Wall -Wextra有警告嗎?如果這樣修復它們。
  5. 確實g ++ -W -Wall -Wextra -ansi有警告?如果這樣修復它們。
  6. 確實g ++ -W -Wall -Wextra -ansi -pedantic有警告嗎?如果這樣修復它們。

在微軟上,嘗試在命令行中添加/ W4來打開警告,再次修復任何問題。

很可能你正在做一些「愚蠢的事情」,而且編譯器可能會幫助你理解它的含義。

編輯:

從與標誌以上,你會看到編譯代碼:

Cust.h:33:錯誤:ISO C++禁止零大小的數組 'ACCTNUM' Cust.h:34 :錯誤:ISO C++禁止零大小數組''acctFN' Cust.h:35:錯誤:ISO C++禁止零大小數組''acctLN' Cust.h:38:錯誤:ISO C++禁止零大小的數組'fileName ' Cust.h:33:錯誤:ISO C++禁止零大小數組'acctNum' Cust.h:34:錯誤:ISO C++禁止零大小的數組''acctFN' Cust.h:35:錯誤:ISO C++禁止零大小數組'acctLN' Cust。h:38:錯誤:ISO C++禁止零大小數組'fileName'

所以你的代碼是無效的C++。您正在將一個名稱複製到一個太小的數組中 - 該數組有0個元素。你真正需要做的是在聲明它們或將它們聲明爲指針時給數組一個大小,然後使用「new」分配適量的memroy。

+0

+1讓計算機捕捉到「愚蠢」的錯誤。爲什麼電腦可以自己做的工作?另外,爲什麼不從第6步開始呢?讓編譯器查找所有錯誤和警告並修復它們。 – 2009-12-04 19:55:43

+0

由於您可以一次性完成所有標記,因此您可以逐漸完成標記,因爲如果您通過現有代碼上的所有標記,就可以一次完成所有錯誤。我曾經在一個代碼庫上工作過,我在60個項目中將選項轉換爲/ W4 ...結果爲100,000個警告......最好分階段執行,以便優先考慮修復程序。對於gcc中的新代碼,我使用了大約13個標誌。 – TofuBeer 2009-12-04 20:09:29

-1

很可能是您的strcpy函數的實現,它可能在如何在Mac上編碼以及如何在Windows上編碼之間存在差異。

2

將無效的緩衝區,過小的緩衝區等傳遞給strcpy會導致未定義的行爲 - 幾乎可能發生任何事情。在Mac上,問題發生但不明顯,而在Windows上則會導致崩潰。

2
char acctNum[]; 
char acctFN[]; 
char acctLN[]; 

有你的問題就在這裏。你似乎從來沒有爲這些字符串的任何地方分配任何空間。 setAcctNum()中的strcpy()溢出未定義數組的邊界,並覆蓋別的東西。實際上,這真是太棒了。

您可能應該使用std :: string,而不是 - 至少會使內存管理更容易。

+0

編譯它並不奇怪。它*非常棒,它運行。你在那裏很幸運。它不能在Windows上運行,因爲Windows有大量檢查(DEP,-GS)來防止這種安全漏洞。同樣,它不會在Linux上運行,因爲它也有類似的檢查(NX和StackGuard)。顯然OSX並不默認這是一個無賴。 – 2009-12-04 19:58:20

+0

有了適當的選項,GCC至少會警告標準C++不支持變長數組。奇怪的是,您可以在單個結構/類中定義多個變長數組,但您永遠無法使用它們中的多個變量。 當然,最初的問題是編輯刪除變長數組,所以這個評論可能沒有意義了... ... – 2009-12-05 22:21:28

相關問題