|
hello Friends
What is Best way to store Array of Dynamic Objects
I am creating a pointer for class A and Initializing 100 objects
And then again I am Initializing 200 objects.
What is Best way to store these arrays.
i used map like map<int,a*> But problem is coming that deleting array pointer is deleting from map also.
My Design Structure is like this
int size =2;
for(int i=0; i<size;i++)
{
A* objA = new A[100]
for(int j = 0 ; j<100;j++)
{
objA[j].var = TempVar;
}
mapA.insert(make_pair(i,objA));
}
But,i am not happy with this way to store array of objects in map .As I am using map as a storage that I can use anywhere in application,and bcoz of not deleting pointer it crashes sometimes.
Suggest me some better way.
Thanks & Regards
Yogesh
|
|
|
|
|
yogeshs wrote: and bcoz of not deleting pointer it crashes sometimes.
The first thing you need to do is find out why your program crashes and fix that problem. I have explained why you cannot delete the objects in your map and the same will hold true if you put them in a fixed array.
|
|
|
|
|
|
Can you use a vector object?
vector class reference[^]
Vector is sequence container.i need some key,data Container.
Linked list is also another option but i dont want to involve in that.
Any Other Ideas?
regards
Yogesh
|
|
|
|
|
I think what AnsHUMAN was implying is that the class std::vector would take care of the allocation and deallocation - it encapsulates the array object and thereby takes away the responsibility from you. You can achieve the same however by defining your own encapsulation: see my response for details.
|
|
|
|
|
yogeshs wrote: bcoz of not deleting pointer it crashes sometimes
Can you clarify that statement, please? Normally, the only abnormal behaviour you can get from not deleting stuff is memory leaks, and, as a result exceptions of the type std::bad_alloc , once you run out of memory. The former will not crash your program though, so may I assume it is the latter? if so, the first thing to do would be to catch that exception.
Apart from that, there's a couple of things you could improve:
1. Storing a map that uses an consecutive integer value as a key indicates that a simple array would do the job just as well, and probably better. The only exception would be if you need to be able to insert values at the start or in the midst of your set later, and you stored key values to specific objects that you want to be able to retrieve later. You haven't mentioned such a requirement, so my advice is to use a C-style array instead. Or, if you need to be able to later add or remove entries, use a std::vector .
2. The objA variable you use to create each entry does contain only one thing, but that thing is being allocated dynamically, on the heap. As you need to make sure this memory gets properly freed again when you no longer need this object, the best way is to make a simple class to hold that variable, and define it's constructor and destructor to automatically allocate and deallocate the memory, as appropriate. That way you no longer need to take care of that anywhere else in your code. See below for an example.
#include <iostream> // for std::cerr
#include <new> // for the definition of std::bad_alloc
class MyData {
private:
A* myobj;
public:
MyData(int size = 100) {
try { myobj = new A[size];
}
catch (std::bad__alloc& ba) {
myobj = 0; throw ba; }
}
~MyData() { if (myobj != 0) { delete [] myobj; }
}
};
int main() {
int error = 0;
MyData *arrayData = 0;
try { arrayData = new MyData[200]; }
catch (std::bad_alloc& ba) {
std::cerr << "Error - bad alloc: " << ba.what() << std::endl;
error = 1;
}
if (arrayData != 0) {
delete [] arrayData; arrayData = 0;
}
return error;
}
P.S.: As I've seen from a more recent response the first point I've raised may not apply to your problem, i. e. you may need a map after all. My point about creating a class to wrap that 100-A array still holds though.
Moreover, you've used a loop to initialize all your A objects. This is another thing you could improve: use your constructor A::A() to do that! If you didn't define one already, do so now:
class A {
A() {
var = TempVar; }
};
|
|
|
|
|
Thanks A lot,I will try as u suggest.
Regards
Yogesh
|
|
|
|
|
Hello
I want to ask one more Question regarding "Moreover, you've used a loop to initialize all your A objects. This is another thing you could improve: use your constructor A::A() to do that!"
I did this in the loop bcoz I am retreiving the size only in that loop.That object array size is not constant. that can also change for each loop.So,thats why i Initialized in the loop inspite of doing in constructor.
Is there any other idea to do this?
Regards
Yogesh
|
|
|
|
|
I suppose in that case, using a loop will be the most obvious solution. You should still define a constructor for A, but instead of allocating the array, just initialize the array pointer to 0, so you can be sure that pointer is at least valid.
You could still avoid the loop and do the allocation in your constructor, but that will take a bit more effort:
#include <iostream> // for std::cerr
#include <new> // for the definition of std::bad_alloc
class MyAllocatorHelper {
public:
virtual void* allocate() const = 0;
}
class MyArrayAllocator {
public:
static MyAllocatorHelper const* p;
static void* makeArray() {
return p ? p->allocate() : 0;
}
}
class MyData {
private:
A* myobj;
public:
MyData();
~MyData() { if (myobj != 0) { delete [] myobj; }
}
};
MyData::MyData() {
try { myobj = MyArrayAllocator::makeArray();
}
catch (std::bad__alloc& ba) {
myobj = 0; throw ba; }
}
class MyDataArray : public MyAllocatorHelper {
private:
MyData* the_array;
std::size_t current_index;
void* allocate() const; public:
MyDataArray(std::size_t size);
MyData* get(std::size_t index);
};
MyDataArray::MyDataArray(std::size_t size) : the_array(0), current_index(0) {
try { the_array = new MyData[size];
}
catch (std::bad_alloc& ba) {
if (the_array != 0) {
delete[] the_array;
the_array = 0;
}
throw(ba); }
}
void* MyDataArray::allocate() const {
A* result = 0;
std::size_t alloc_size = 0;
++current_index;
try {
result = new A[alloc_size];
}
catch (std::bad_alloc& ba) {
throw(ba);
}
return result;
}
int main() {
int error = 0;
MyDataArray* arrayData = 0;
try { arrayData = new MyDataArray(200);
}
catch (std::bad_alloc& ba) {
std::cerr << "Error - bad alloc: " << ba.what() << std::endl;
error = 1;
}
if (arrayData != 0) {
delete arrayData;
arrayData = 0;
}
return error;
}
I wrote this a bit in a hurry and didn't take the time to test it, there may even be typos. However, I hope even if this doesn't compile it might give you an idea of what I did here:
1. An abstract interface for allocating some unspecified data, which later gets implemented by the wrapper to your data array.
2. A 'static class' that your constructors can access without having to rely on parameters.
3. A local counter variable 'current_index' that keeps track of the number of allocations that have already taken place, implying the index of the data object within your array. You can use this counter to determine the correct size for that particular object in your array.
|
|
|
|
|
Hi!! I'd like to know if function WriteAllText is avalaible in a MFC project.
If not, ¿which other options are to save a text file? So that you can't use:
escritura << "Example";
Thanks!!
|
|
|
|
|
I'd like to help, but I'm not sure what you're asking. What is "WriteAllText"?
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
|
i52camam wrote: Okay, I'm sorry. WriteAllText is a function of the namespace System.IO:
And System.IO is part of the .NET framework, but MFC uses only native code.
If you need to work with files, MFC has the CFile[^] class.
"Real men drive manual transmission" - Rajesh.
|
|
|
|
|
yes, there is such a thing.
the << operator can be used for such.
or you can use the "standard c" library. There are many ways to accomplish what is wanted.
I'll give you the C++ way.
#include "stdafx.h"
#include <fstream>
using namespace std;
int main() {
fstream file;
file.open("filename.txt");
string foo = "here's some text";
file << foo;
file.close();
return 0;
}
See fstream[^] docs.
If you want to use "MFC" there is CFile[^]
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Hi,
I've been using the CFile class unsuccessfully, cause the file doesn't get created. Here is my code:
void Guardar::OnBnClickedGuardar()
{
SaveToFile();
}
void Guardar::SaveToFile()
{
CString nombre=_T("\D:\Write_File.dat");
CFile cfile;
cfile.Open(nombre , CFile::modeCreate | CFile::modeReadWrite);
char pbufWrite[100];
memset(pbufWrite, 'a', sizeof(pbufWrite));
cfile.Write(pbufWrite, 100);
cfile.Flush();
}
Also, I have debugged the program and all the functions are called step by step.... so I don't know where is the problem
Thanks for all.
|
|
|
|
|
i52camam wrote:
CString nombre=_T("\D:\Write_File.dat"); remove the leading slash (\) so that it reads:
CString nombre=_T("D:\\Write_File.dat");
finally after the
cfile.Flush();
line write
cfile.Close();
The last is probably not strictly necessary since the CFile destructor will likely close the file.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
modified 10-Oct-11 15:28pm.
|
|
|
|
|
Now I can operate Excel with ADO, but that way I treat Excel as a database.
I have no idea how to deal with Exel which has irregular data.
And I don't how to deal with the cell format, say I want the background of cells to be red, and the font color to be green and so on.
The tutorial of MSDN about Excel is wirite in VBA. I can't find tutorials about programming Excel with VC++.
Appreciate any help l can get!
|
|
|
|
|
Falconapollo wrote: And I don't how to deal with the cell format, say I want the background of cells to be red, and the font color to be green and so on.
Sounds like you need Excel Automation (i.e., COM). There are several examples of such here on CP.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
This question was already posted in Q&A[^]; please post in one location only.
0100000101101110011001000111001011101001
|
|
|
|
|
How to read a packet using c language code
|
|
|
|
|
Go to one of the protocol web sites and find out what the packet looks like, then create a 1 packed struct to mimic it. Then cast the data as a pointer to that packet and access the fields via the struct members.
#pragma pack (push, 1)
...struct here
#pragma pack (pop)
==============================
Nothing to say.
modified 7-Oct-11 2:59am.
|
|
|
|
|
Packet of?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
DavidCrow wrote: Packet of?
Pork Scratchings?
(Hmmm, deep fried salty pig skin.....)
==============================
Nothing to say.
|
|
|
|
|
|
There are a lot of webistes that document network protocols. Normally, create a struct, 1 byte packed, that mimics this protocol. THen casting the data to that struct, tear it apart.
If you need more help than that, get a different job.
==============================
Nothing to say.
|
|
|
|