2009-12-04 85 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

相关问题