I have created a class and tried to initialize a 2D pointer in my class constructor. Then I use a getter in my main.cpp but it doesn't worked. Building is successful but I end up with a value 0xcccccccc? when I debug it.
Here is my code.
Header
Asset {
public:
Asset(int numberAssets, int numberReturns); // Constructor
//getter and setter
double **getAssetReturnMatrix();
~Asset();
private:
int _numberAssets, _numberReturns;
double **_assetReturn;
};
Cpp file
#include "Asset.h"
Asset::Asset(int numberAssets, int numberReturns)
{
// store data
_numberAssets = numberAssets; // 83 rows
_numberReturns = numberReturns; // 700 cols
//allocate memory for return matrix
double **_assetReturn = new double*[_numberAssets]; // a matrix to store the return data
for (int i = 0; i<_numberAssets; i++)
_assetReturn[i] = new double[_numberReturns];
}
Asset::~Asset()
{
}
Main.cpp
#include <iostream>
#include "read_data.h"
#include "Asset.h"
using namespace std;
int main(int argc, char *argv[])
{
//Create our class object
int numberAssets = 83;
int numberReturns = 700;
Asset returnMatrix = Asset(numberAssets, numberReturns);
//read the data from the file and store it into the return matrix
string fileName = "asset_returns.csv";
double ** data = returnMatrix.getAssetReturnMatrix();
cout << data; // <--- Value 0xcccccccc? here
//readData(data, fileName);
return 0;
}
Could you please tell me where I am wrong?
Thanks a lot !
I was created a new variable which had nothing to do with my private member double **_assetReturn defined in my h file, here:
//allocate memory for return matrix
double **_assetReturn = new double*[_numberAssets]; // a matrix to store the return data
for (int i = 0; i<_numberAssets; i++)
_assetReturn[i] = new double[_numberReturns];
Changed it to:
//allocate memory for return matrix
this->_assetReturn = new double*[this->_numberAssets]; // a matrix to store the return data
for (int i = 0; i<this->_numberAssets; i++)
this->_assetReturn[i] = new double[this->_numberReturns];
Worked fine now.
Related
When I create a double Linklist By using C(C99), if I add the code: struct DNonde***first**=NULL; on the main function when running Display function the parameter first = NULL. If I remove the additional code: struct DNonde *first = NULL; then structure point: first will normally running as the linklist's first node's address and the Display funtion will also normally running.
However the question is I am using the Create function to create double Linklist after the code:struct DNonde*first=NULL;thus, it will not influence the latter codes, and when I debug the codes it shows me that the double Linklist is created successfully but when in Display function the first = NULL. And why it cause that?
Below is the source code
#include "stdio.h"
#include "stdlib.h"
struct DNonde
{
struct DNonde *preview;
int data;
struct DNonde *next;
}*first=NULL;
void Create(int a[],int length)
{
struct DNonde*tem = NULL;
first =(struct DNonde*)malloc(sizeof(struct DNonde));
first->preview=NULL; first->data=a[0]; first->next=NULL;
struct DNonde *control = first;
for(int i=1;i<length;i++)
{
tem =(struct DNonde*)malloc(sizeof(struct DNonde));
control->next = tem;
tem->preview = control; tem->data = a[i]; tem->next=NULL;
control = tem;
}
}
void Display(struct DNonde*first)
{
do
{
printf("%d ",first->data);
first=first->next;
}while(first != NULL);
}
int main()
{
int a[]={1,3,4,5};
struct DNonde*first=NULL;
Create(a, 4);
Display(first);
}
I'm having a problem where I am using Boost Interprocess to write some values to shared memory using managed_shared_memory::construct() then in another process trying to read those values using managed_shared_memory::find() but it is not coming back with the same address that was created using construct().
I took the sample code from the Boost Interprocess documentation for Creating named shared memory objects and split into two different programs and the same thing is happening.
interprocess_write.cpp
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <cstddef>
#include <cassert>
#include <iostream>
#include <utility>
int main(int argc, char *argv[])
{
using namespace boost::interprocess;
typedef std::pair<double, int> MyType;
if(argc == 1){ //Parent process
shared_memory_object::remove ("MySharedMemory");
//Construct managed shared memory
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//Create an object of MyType initialized to {0.0, 0}
MyType *instance = segment.construct<MyType>
("MyType instance") //name of the object
(0.0, 0); //ctor first argument
//Create an array of 10 elements of MyType initialized to {0.0, 0}
MyType *array = segment.construct<MyType>
("MyType array") //name of the object
[10] //number of elements
(0.0, 0); //Same two ctor arguments for all objects
//Create an array of 3 elements of MyType initializing each one
//to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...
float float_initializer[3] = { 0.0, 1.0, 2.0 };
int int_initializer[3] = { 0, 1, 2 };
MyType *array_it = segment.construct_it<MyType>
("MyType array from it") //name of the object
[3] //number of elements
( &float_initializer[0] //Iterator for the 1st ctor argument
, &int_initializer[0]); //Iterator for the 2nd ctor argument
std::cout << array << ":" << instance << ":" << array_it << std::endl;
//Check child has destroyed all objects
if(segment.find<MyType>("MyType array").first ||
segment.find<MyType>("MyType instance").first ||
segment.find<MyType>("MyType array from it").first)
return 1;
}
return 0;
}
interprocess_read.cpp
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //std::system
#include <cstddef>
#include <cassert>
#include <iostream>
#include <utility>
int main (int argc, char **argv)
{
using namespace boost::interprocess;
typedef std::pair<double, int> MyType;
//Open managed shared memory
managed_shared_memory segment(open_only, "MySharedMemory");
std::pair<MyType*, managed_shared_memory::size_type> res;
//Find the array
res = segment.find<MyType> ("MyType array");
//Length should be 10
if(res.second != 10) return 1;
std::cout << res.first << ":";
//Find the object
res = segment.find<MyType> ("MyType instance");
//Length should be 1
if(res.second != 1) return 1;
std::cout << res.first << ":";
//Find the array constructed from iterators
res = segment.find<MyType> ("MyType array from it");
//Length should be 3
if(res.second != 3) return 1;
std::cout << res.first << std::endl;
//We're done, delete all the objects
segment.destroy<MyType>("MyType array");
segment.destroy<MyType>("MyType instance");
segment.destroy<MyType>("MyType array from it");
}
When I ran the interprocess_write program I got the following output:
0x1260128:0x12600d8:0x1260208
But when I run the interprocess_read program I get:
0x2ad0128:0x2ad00d8:0x2ad0208
Is there something missing that has to be done in interprocess_read to make it pull the correct addresses out of shared memory?
After creating a hash table and assigning each letter to a value for the table, i am noticing the first word output by the table for the beginning of every linked list is the same word. Somehow it seems I am transferring the entire dictionary to each array in the table even though I have attempted to separate them. Any assistance would be awesome! Thanks in advance
// Implements a dictionary's functionality
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char *word;
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 25;
// Hash table
node *table[N];
char lowerword[LENGTH+1];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
int bucketfind = 0;
int x = 0;
for (int b = word[x]; b != '\0';b = word[x], x++)
{
int lowertemp = tolower(word[x]);
if (x == 0)
{
bucketfind = lowertemp - 97;
}
char lowerfinal = lowertemp;
lowerword[x] = lowerfinal;
//printf("%c", lowerword[x]);
}
int wordlen = x + 1;
int pr = 0;
while (table[bucketfind] -> next != NULL)
{
int dwlen = strlen(table[bucketfind]-> word);
pr++;
//printf("%i, %i, %s, %i\n", pr, dwlen, table[bucketfind] -> word, bucketfind);
}
//TODO
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
int asciifirst = word[0];
int lowerfirst = tolower(asciifirst);
int bucketnum = lowerfirst - 97;
return bucketnum;
}
// Loads dictionary into memory, returning true if successful else false
int dictwords = 0;
//char *cword = (char*)malloc(sizeof(char)*46);
bool load(const char *dictionary)
{
char *cword = malloc(sizeof(char)*46);
FILE *dict = fopen(dictionary, "r");
if (dictionary == NULL)
{
return false;
}
int x = 0;
while ((fscanf(dict, "%s", cword) != EOF))
{
node *nword = malloc(sizeof(node));
nword -> word = cword;
nword -> next = NULL;
int bucket = hash(cword);
//printf("%i\n", bucket);
if (table[bucket] != NULL)
{
nword -> next = table[bucket];
table[bucket] = nword;
}
else
{
table[bucket]= nword;
}
dictwords++;
}
fclose(dict);
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
return dictwords;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// TODO
return false;
}
It's not just the first word; every word in the linked list is the same word (the last one read). cword gets 46 bytes of memory at a specific address here char *cword = malloc(sizeof(char)*46);. Every word from dictionary is read into that same address.
read folder tree from a Rest API, then show them to user
Example json response after call API:
[
{"name":"/folder1/file1.txt";"size":"1KB"},
{"name":"/folder1/file2.txt";"size":"1KB"},
{"name":"/folder1/sub/file3.txt";"size":"1KB"},
{"name":"/folder2/file4.txt";"size":"1KB"},
{"name":"/folder2/file5.txt";"size":"1KB"}
]
I only want to make GUI like below image:
There are 2 options:
QTreeView
QTreeWidget
In this photo, I used QTreeWidget (with static data).
Currently, I don't know make data model for this.
I made TreeModel to set data for QtreeView.
But When them shown in GUI, All of the data only show in column Name.
I copied the code from http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
But now I can't resolve this problem. I need an example source code for this.
Plus, I also only want show a tree view simply.
don't use QFileSystem because data get from Rest API.
What you have to do is parsing the json by getting the name of the file and the size, then you separate the name using the "/", and add it to the model in an appropriate way.
#include <QApplication>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QStandardItemModel>
#include <QTreeView>
#include <QFileIconProvider>
QStandardItem * findChilItem(QStandardItem *it, const QString & text){
if(!it->hasChildren())
return nullptr;
for(int i=0; i< it->rowCount(); i++){
if(it->child(i)->text() == text)
return it->child(i);
}
return nullptr;
}
static void appendToModel(QStandardItemModel *model, const QStringList & list, const QString & size){
QStandardItem *parent = model->invisibleRootItem();
QFileIconProvider provider;
for(QStringList::const_iterator it = list.begin(); it != list.end(); ++it)
{
QStandardItem *item = findChilItem(parent, *it);
if(item){
parent = item;
continue;
}
item = new QStandardItem(*it);
if(std::next(it) == list.end()){
item->setIcon(provider.icon(QFileIconProvider::File));
parent->appendRow({item, new QStandardItem(size)});
}
else{
item->setIcon(provider.icon(QFileIconProvider::Folder));
parent->appendRow(item);
}
parent = item;
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStandardItemModel model;
model.setHorizontalHeaderLabels({"Name", "Size"});
const std::string json = R"([
{"name":"/folder1/file1.txt";"size":"1KB"},
{"name":"/folder1/file2.txt";"size":"1KB"},
{"name":"/folder1/sub/file3.txt";"size":"1KB"},
{"name":"/folder2/file4.txt";"size":"1KB"},
{"name":"/folder2/file5.txt";"size":"1KB"}
])";
QJsonParseError parse;
// The string is not a valid json, the separator must be a comma
// and not a semicolon, which is why it is being replaced
QByteArray data = QByteArray::fromStdString(json).replace(";", ",");
QJsonDocument const& jdoc = QJsonDocument::fromJson(data, &parse);
Q_ASSERT(parse.error == QJsonParseError::NoError);
if(jdoc.isArray()){
for(const QJsonValue &element : jdoc.array() ){
QJsonObject obj = element.toObject();
QString name = obj["name"].toString();
QString size = obj["size"].toString();
appendToModel(&model, name.split("/", QString::SkipEmptyParts), size);
}
}
QTreeView view;
view.setModel(&model);
view.show();
return a.exec();
}
Note: the semicolon is not a valid separator for the json, so I had to change it.
I have a class ClientWindow. I have created several instances of it and appended the their pointers to a a list. If i try to show any of the windows however, I get "Segmentation fault (core dumped)" I keep the list of windows in a class called controller.
Here is my controller header file:
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "clientwindow.h"
class Controller
{
public:
Controller();
void createClients(int num);
void showWindows();
private:
QList<ClientWindow*> clWList;
int size;
};
#endif // CONTROLLER_H
this is the cpp file:
#include "controller.h"
Controller::Controller()
{
}
void Controller::createClients(int num)
{
size = num;
for(int i = 0; i < size; i++)
{
ClientWindow cw;
clWList.append(&cw);
}
}
void Controller::showWindows()
{
for(int i = 0; i < size; i++)
{
ClientWindow* cw = clWList.at(0);
cw->show();
}
}
this is my main:
#include <QtGui/QApplication>
#include "clientwindow.h"
#include "controller.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// ClientWindow w;
// w.show();
QString temp = argv[1];
bool ok;
int tempI = temp.toInt(&ok, 10);
Controller c;
c.createClients(tempI);
c.showWindows();
return a.exec();
}
This is where it goes wrong:
for(int i = 0; i < size; i++)
{
ClientWindow cw;
clWList.append(&cw);
}
A local variable cw is created on the stack in each iteration. It is deallocated at the end of each iteration. Meaning the data is gone. So you end up storing pointers pointing to junk.
Calling a member function of a junk typically results in crash. :) Do this instead:
for(int i = 0; i < size; i++)
{
ClientWindow * cw = new ClientWindow();
clWList.append(cw);
}
You'll have to go through the list and delete the objects after you are done with them.