C++程序运行内存错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++程序运行内存错误相关的知识,希望对你有一定的参考价值。
程序抽象了一个稀疏矩阵,用一个二维数据表示(元素为0或1)非零元的位置,另一个一维数据顺序存放非零元的值,程序函数运行都没有问题,错误好像是出在SpaseMatrix的析构函数上,就是释放内存空间的语句,如果将两个delete语句删除,则可以正常运行,但这样会不会导致内存泄漏?
程序代码如下:
//SparseMatrix.h
#ifndef SPARSEMATRIX_H
#define SPARSEMATRIX_H
class SparseMatrix
public:
SparseMatrix(int r, int c, int num);
~SparseMatrix();
void setBits(int rMulc);
void setA(int x, int value);
SparseMatrix* AddMatrix(SparseMatrix b);
int getN();
int getM();
int getNums();
int* getBits();
int* getA();
private:
int n,m;//记录m*n阶矩阵的维数
int nums;//记录矩阵中非零元的个数,即一维数组的维数
int* bits;
int* a;
;
#endif
//SparseMatrix.cpp
#include "SparseMatrix.h"
SparseMatrix::SparseMatrix(int r, int c, int num):m(r), n(c), nums(num)
bits = new int[m*n];
for (int i=0; i<m*n; i++)
*(bits + i) = 0;
a = new int[nums];
for (int j=0; j<nums; j++)
*(a + j) = 0;
SparseMatrix::~SparseMatrix()
// delete[] bits;
// delete[] a;
void SparseMatrix::setBits(int rMulc)
*(bits + rMulc) = 1;
void SparseMatrix::setA(int x, int value)
*(a+x) = value;
SparseMatrix* SparseMatrix::AddMatrix(SparseMatrix b)
SparseMatrix* sum = new SparseMatrix(m, n, nums + b.getNums());
int j = 0;//记录和矩阵的非零元次序
int k = 0;//记录被加矩阵非零元的次序
int l = 0;//记录参数矩阵非零元的次序
for (int i=0; i<m*n; i++)
if ((*(bits+i) == 0) && ((*(b.getBits()+i)) == 0))
continue;
else if ((*(bits+i) == 0) && ((*(b.getBits()+i)) == 1))
sum->setBits(i);
sum->setA(j, *(b.getA()+l));
j++;
l++;
else if ((*(bits+i) == 1) && ((*(b.getBits()+i)) == 0))
sum->setBits(i);
sum->setA(j, *(a + k));
j++;
k++;
else if((*(bits+i) == 1) && ((*(b.getBits()+i)) == 1))
sum->setBits(i);
sum->setA(j, (*(a + k)) + *(b.getA() + l));
j++;
k++;
l++;
return sum;
int* SparseMatrix::getBits()
return bits;
int* SparseMatrix::getA()
return a;
int SparseMatrix::getM()
return m;
int SparseMatrix::getN()
return n;
int SparseMatrix::getNums()
return nums;
字数超了,我打在补充里面~
//main.cpp
#include<iostream>
using namespace std;
#include"SparseMatrix.h"
void main()
int m, n, value;
int num;
cout << "输入矩阵的维数(行 列):"<< endl;
cin >> m >> n;
cout << "输入非零元个数:" << endl;
cin >> value;
SparseMatrix a(n, m, value);
int r,c;
for (int i=0; i< value; i++)
cout << "输入第" << (i+1) << "个非零元的行列值" << endl;
cin >> r >> c;
cout << "输入这个元素的值:" << endl;
cin >> num;
a.setBits(r*n+c);
a.setA(i,num);
cout << "第二个矩阵:" << endl;
cout << "输入矩阵的维数(行 列):"<< endl;
cin >> m >> n;
cout << "输入非零元个数:" << endl;
cin >> value;
SparseMatrix b(m, n, value);
for (int i=0; i< value; i++)
cout << "输入第" << (i+1) << "个非零元的行列值" << endl;
cin >> r >> c;
cout << "输入这个元素的值:" << endl;
cin >> num;
b.setBits(r * n + c);
b.setA(i,num);
SparseMatrix* sum = a.AddMatrix(b);
字数不够,不能打输出了,但错误和输出没什么关系,请帮我看下,谢谢了~
对于你的程序,这个问题体现在SparseMatrix* sum = a.AddMatrix(b);这句话上,你看着简单的把b作为参数传了进去,但是因为你采用的是值传递,所以,编译器会在AddMatrix函数体内为你生成一个b的拷贝,这是调用了拷贝构造函数,而你是采用默认拷贝构造函数,所以这个拷贝的成员bits和a这两个数组的指针实际上和b的是一样的,在函数执行完以后,编译器会释放掉这个临时的拷贝,调用了析构函数,删掉了bits和a,注意,这时b的成员bits和a也被删掉了。而在main函数结束时,b和a都要被释放掉,所以当b执行析构的时候就会再次删除原本已经delete掉的bits和a数组,所以导致了错误。
建议改正的地方:
1>如果有指针成员的话一定要自己写拷贝构造函数。
2>函数传值如果传的是自定义类型,而且你不会对这个值在函数内做改变,那么建议传入const 引用类型,这样可以省掉生成临时拷贝的步骤。
3>写程序时,变量名要有意义,不要全都是a,b之类的。。。调试起来都麻烦。。。
对于你这个程序,简单的修改方案如下:
在类内加入这个拷贝构造函数
SparseMatrix(const SparseMatrix& sm)
n = sm.n;
m = sm.m;
nums = sm.nums;
bits = new int[nums];
a = new int[n*m];
参考技术A 我是vc6.0写的大家帮我看下为什么一运行就出现内存错误,这个程序我是想看你定义的结构体指针没有分配空间,不能进行赋值操作。你可以用动态分配,也
C++ 内存分段错误?
【中文标题】C++ 内存分段错误?【英文标题】:C++ Memory Segmentation Fault? 【发布时间】:2016-03-21 09:13:50 【问题描述】:我编写了一个程序,该程序从谷歌金融获取股票数据并执行买入/卖出决策。我在 Visual Studio C++ 中编写了它,它在 Windows 上运行良好,但是当我尝试在 ubautu 上使用 g++ -std=c++11 stock.cpp
编译它并运行 a.out 时,我遇到了 seg 错误。我哪里错了?
从 main(),第二次调用 SMA() 时出错:
decisionPoint_model_call();
//this function call a function called SMA() twice to calculate two different moving averages
//the second time SMA() is called from inside decisionPoint_model_call() a seg. fault occurs
gdb 给了我以下错误:
0xb7f42ac5 in std::basic_ostream >& std::operator(std::basic_ostream >&, std::basic_string, std::allocator > const&) () 来自 /usr/lib /i386-linux-gnu/libstdc++.so.6
代码如下:
stock.cpp
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
#include <deque>
using namespace std;
int numberOfDays; //total number of days
int dayNumber = 0; //0 being the starting date
struct each_day
string date;
float open;
float high;
float low;
float close;
float volume;
float mov_avg[1];
;
each_day *day = nullptr;
//store parced cotents in structure one day at a time
void float2structure(string date, float open, float high, float low, float close, float volume)
if (dayNumber == 0)
day = new each_day[numberOfDays];
day[dayNumber].date = date;
day[dayNumber].open = open;
day[dayNumber].high = high;
day[dayNumber].low = low;
day[dayNumber].close = close;
day[dayNumber].volume = volume;
if (dayNumber != numberOfDays)
dayNumber++;
void line2float(string line_string) //reads line and converts appropriate type
string date;
float open;
float high;
float low;
float close;
float volume;
string temp;
int dataBlocks = 1;
istringstream ss(line_string);
while (!ss.eof())
switch (dataBlocks)
case 1:
getline(ss, date, ',');
case 2:
getline(ss, temp, ',');
if (temp == "-")
temp = "0";
open = stof(temp);
case 3:
getline(ss, temp, ',');
if (temp == "-")
temp = "0";
high = stof(temp);
case 4:
getline(ss, temp, ',');
if (temp == "-")
temp = "0";
low = stof(temp);
case 5:
getline(ss, temp, ',');
if (temp == "-")
temp = "0";
close = stof(temp);
case 6:
getline(ss, temp, ',');
if (temp == "-")
temp = "0";
volume = stof(temp);
float2structure(date, open, high, low, close, volume);
//gets line, sort in correct order, send each line to next function
void lineGet(ifstream &inFile)
cout << "Reorganizing data... be patient..." << endl;
vector<string> lines_in_reverse;
string line;
while (getline(inFile, line))
// Store the lines in reverse order.
lines_in_reverse.insert(lines_in_reverse.begin(), line);
numberOfDays = lines_in_reverse.size() - 1;
for (int x = 0; x < numberOfDays; x++)
line2float(lines_in_reverse[x]);
//calculed the SMA and stores that in data.mov_avg[x]
void SMA(int movingAvg, int mv_num)
deque <float> sma;
float smaSize = (float)movingAvg;
float sum_of_elems = 0;
for (dayNumber = 0; dayNumber < numberOfDays; dayNumber++)
cout << day[dayNumber].date << " " <<dayNumber<<endl;
if (dayNumber <= smaSize - 1)
sma.push_front(day[dayNumber].close);
day[dayNumber].mov_avg[mv_num] = 0; //ERROR HERE?
if (dayNumber == smaSize - 1)
for (float n : sma)
sum_of_elems += n;
day[dayNumber].mov_avg[mv_num] = sum_of_elems / smaSize;
else
sum_of_elems = 0;
sma.pop_back();
sma.push_front(day[dayNumber].close);
for (float n : sma)
sum_of_elems += n;
day[dayNumber].mov_avg[mv_num] = sum_of_elems / smaSize;
//function to analyze data and report trades
void decisionPoint_model(string startDate)
dayNumber = 0;
bool holdingLong = false;
bool shortSell = false;
float totalProfit = 0;
float buyPrice;
float sellPrice;
float shortPrice;
float coverPrice;
//loop though each day, compare moving averages, buy and sell based on moving averages
for (; dayNumber < numberOfDays; dayNumber++)
//cout << day[dayNumber].moving_avg[0] << " " << day[dayNumber].moving_avg[1] << endl;
if (day[dayNumber].mov_avg[1] != 0)
if (day[dayNumber].mov_avg[0] < day[dayNumber].mov_avg[1] && holdingLong == true)
//sell
sellPrice = day[dayNumber + 1].open;
totalProfit += (sellPrice - buyPrice);
cout << "Sell: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << endl;
cout << "Profit from trade: $" << sellPrice - buyPrice << endl;
cout << "Total profit: $" << totalProfit << endl;
cout << endl;
holdingLong = false;
if (day[dayNumber].mov_avg[0] < day[dayNumber].mov_avg[1] && shortSell == false)
//short
shortPrice = day[dayNumber + 1].open;
cout << "Short: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << ", ";
shortSell = true;
if (day[dayNumber].mov_avg[0] > day[dayNumber].mov_avg[1] && shortSell == true)
//cover
coverPrice = day[dayNumber + 1].open;
totalProfit += (shortPrice - coverPrice);
cout << "Cover: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << endl;
cout << "Profit from trade: $" << shortPrice - coverPrice << endl;
cout << "Total profit: $" << totalProfit << endl;
cout << endl;
shortSell = false;
if (day[dayNumber].mov_avg[0] > day[dayNumber].mov_avg[1] && holdingLong == false)
//buy
buyPrice = day[dayNumber + 1].open;
cout << "Buy: $" << day[dayNumber + 1].open << " on " << day[dayNumber + 1].date << ", ";
holdingLong = true;
cout << endl;
cout << "Total profits from strategy: $" << totalProfit << endl;
cout << endl;
void decisionPoint_model_call()
cout << "testing end" << endl;
cout << "\nWe are going to perfrom a decision point analysis." << endl;
cout << "This requires two moving averages relatively close by (eg. 10 and 15 day moving averages)." << endl;
cout << endl;
int movingavg;
cout << "Set the first moving average (ex. 10):";
cin >> movingavg;
SMA(movingavg, 0);
cout << endl;
cout << "Set the second moving average (ex. 15):";
cin >> movingavg;
SMA(movingavg, 1); //ERROR OCCURS THE SECOND TIME WE CALL SMA()
cout << "\nData stretches from: " << day[0].date << " to " << day[numberOfDays - 1].date << endl;
cout << "NO ERROR" << endl;
string startDate;
cout << "Enter a date to begin analysis: ";
cin >> startDate;
cout << endl;
decisionPoint_model(startDate);
cout << "Open price on first day (given data): $" << day[0].open << endl;
cout << "Close price on last day (given data): $" << day[numberOfDays - 1].close << endl;
cout << "For a total price change of: $" << day[numberOfDays - 1].close - day[0].open << endl;
cout << endl;
void file_get()
functionStart:
string filename;
cout << "\nEnter file name (ex. goog.csv):";
cin >> filename;
ifstream inFile(filename.c_str());
if (inFile.is_open())
cout << "\nLoading file...\n" << endl;
lineGet(inFile);
inFile.close();
else
cout << "No file was found on disk, retrieving one from the web..." << endl;
system("python stockFetch.py");
goto functionStart;
int main()
cout << endl;
cout << "What type on analysis would you like to perform?" << endl;
cout << "1. Decision Point Analysis - based on historical data." << endl;
cout << endl;
cout << "Enter number: "; //only number that works is 1 currently
int analysisNumber;
cin >> analysisNumber;
switch (analysisNumber)
case 1:
file_get();
//order of calls: 1.file_get() -> 2.lineGet() -> 3.line2float() -> 4.float2structure()
//function 2 - 4 are called over and over again to store each line from the cvs file to the structure
decisionPoint_model_call();
//this function call function called SMA() twice to calculate two different moving averages
//the second time SMA() is called from inside decisionPoint_model_call() a seg. fault occurs
system("pause");
return 0;
要获取股票数据文件,您需要从here获取csv文件并将其保存为aapl.csv
。
或者保存以下 python 文件,因为如果 c++ 程序在磁盘上找不到 .csv 文件,它会调用它。
stockFetch.py
import sys, os, urllib
#get the csv file from google finance
tickerSymbol= raw_input('Enter the ticker symbol: ')
startDate = raw_input('Enter the start date(Ex. Jan 20, 2015): ')
endDate = raw_input('Enter the end date: ')
startDate.replace (" ", "+")
startDate.replace (",", "2C")
endDate.replace (" ", "+")
endDate.replace (",", "2C")
url = "http://www.google.com/finance/historical?q="+str(tickerSymbol)+"&startdate="+str(startDate)+"&enddate="+str(endDate)+"&output=csv"
urllib.urlretrieve(url, str(tickerSymbol))
if os.path.isfile(str(tickerSymbol)):
os.rename(str(tickerSymbol), str(tickerSymbol)+".csv")
print ("--File Fetched--")
sys.exit()
print ("--Could not find file--")
【问题讨论】:
请发帖minimal reproducible example。关键字 - 最小。 或者使用调试器。您至少需要使用基本的调试技能来查找崩溃发生的位置,然后在您不明白为什么时提出问题。您可能正在对向量和字符串的大小做出假设,或者做一些坏事,例如从零的无符号值中减去 1。 【参考方案1】:我不知道这是否是唯一的错误,但确实是一个错误。
您定义大小为 1 的 each_day::mov_avg
float mov_avg[1];
但在位置2使用
day[dayNumber].mov_avg[mv_num] = 0; //ERROR HERE? (yes, when mv_num == 1)
[...]
day[dayNumber].mov_avg[mv_num] = sum_of_elems / smaSize;
[...]
day[dayNumber].mov_avg[mv_num] = sum_of_elems / smaSize;
[...]
if (day[dayNumber].mov_avg[1] != 0)
if (day[dayNumber].mov_avg[0] < day[dayNumber].mov_avg[1] && holdingLong == true)
[...]
尝试定义
float mov_avg[2];
【讨论】:
以上是关于C++程序运行内存错误的主要内容,如果未能解决你的问题,请参考以下文章