我在Windows上没有在Mac上出现strcpy错误?

时间:2009-12-04 18:32:43

标签: windows string macos compatibility

- 所有修改过的代码仍然拒绝运行,请帮忙 -

当我在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      P3.exe!_FreeLibrary@4() 
 5      P3.exe!@ILT+170(__except_handler4)() 
 6      kernel32.dll!75eb3677() 
 7      ntdll.dll!77b29d72() 
 8      ntdll.dll!77b29d45() 

4 个答案:

答案 0 :(得分: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有警告吗?如果有,请修理它们。
  7. 在微软上尝试将/ 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。

答案 1 :(得分:2)

将无效缓冲区,太小的缓冲区等传递给strcpy会导致未定义的行为 - 几乎任何事情都可能发生。在Mac上,问题发生但不明显,而在Windows上则会导致崩溃。

答案 2 :(得分:2)

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

那里有你的问题。你似乎永远不会为这些字符串分配任何空间。 setAcctNum()中的strcpy()溢出了该unsized数组的边界,并覆盖了其他内容。实际上,这完全可以编译,这真是太神奇了。

您可能应该使用std :: string,而不是 - 这将使内存管理更容易,至少。

答案 3 :(得分:-1)

可能是你的strcpy函数的实现,它可能在mac上编码的方式与它在Windows上的编码方式有所不同。