I'm doing my homework (and learn how C++ works).
My task is:
Define some class with field...(never mind)
create an vector and array from these object and iterate it! (listing, average by field,etc).
Now it's correctly works with vector, but array doesnot work:
static Cipo* cipok; // object array
static int cep = 0; // endpoint index
static int ccap = 0; // array size
Default assignmet opearator for Cipo:
public: Cipo& operator=(const Cipo &c)
{
return ((Cipo&)c);
}
Initalization:
cipok = (Cipo*) malloc(sizeof(Cipo*)*100); // new Cipo[num] doesn't work..
ccap = 100;
Test code:
for (int i = 0; i < 5; i++)
{
Cipo c(43.5, "str", 12670, false, false);
std::cout << c.ar <<" ";
cipok[cep] = c;
std::cout << cipok[cep].ar << " ";
cep++;
}
And the result:
12670 0 12670 0 12670 0 12670 0 12670 0
But objects not "disappeared" if I use vector, push_back() the objects and read from the vector with direct indexing (or with iterators). Why do they exhibit this behaviour?
You immediate problem is likely caused by whacky implementation of operator = that does absolutely nothing. I'd recommend step through the code in debugger to see it. operator = (and copy constructor) should properly copy values into destination object.
There are many other issues with the code - your naming convention is ... interesting, you seem to try to cast whatever you have to whatever result is required for code to compile without reasoning what should actually be done. malloc in C++ code is very rarely needed...
I think the general problem is, I'm programming always in java (but now in university i must prog. in C/C++, naming conventions, like in java and in hungarian the Cipő is meaning Shoe). And in Java there is no pointers, and all object always acces by reference, but looks like (as i tested ) if i create a new object array the C++ will not allocate only 100 pointer which points to the object (where the object data starts), it allocated 100*sizeof(object) and for this place i can add data trougth assing operator.
it's my teory true?
So i tried to manage Object acces like in java.
Why copy the Object if itself alredy exist? (I don't like to "clone" objects).
Related
As the title says - I need the content of the v array not to change outside of the function.
I thought that it would not happen (because AFAIK the default behavior of arrays is to deep copy - but it looks like it is not).
#include <iostream>
using namespace std;
void testModif(int *v)
{
for (int i = 0; i < 5; i++)
{
v[i]++;
}
}
int main()
{
int *v;
v = new int[100];
*v = 0;
testModif(v);
for (int i = 0; i < 5; i++)
{
cout << v[i] << " ";
}
}
How can I make v not change after running testModif?
First you can enlist the compilers help by declaring as
void testModif(const int *v);
I.e. as v being a non-const pointer to const int. I.e. you can e.g. increment the copy of the pointer, but not change what the pointer points to.
With that change the shown code will get errors/warnings, which at least tell you that you are doing what you do not want to do.
Then you need to change your code to follow your self-decided rule.
For the shown code that would require making a copy of the array itself (not only of the pointer pointing to it). Exactly, that would match "deep copy" in contrast to the "shallow copy" you mention.
Most closely to your shown code would be a local copy, an array of size 5 (magic number, but you know what I mean) or something malloced of proper size (and of course freed before leaving the function).
Obviously making a local copy, incrementing all members and then leaving the function again normally would seem pointless. I trust that this is purely to be blamed to you making an appropriate MRE. I.e. the point that intentionally not changing the original values and only locally incrementing is what you want to achieve.
Of course I am not contradicting the comments to your question, which recommend the more C++ way of doing things, with standard containers, like std::array, std::vector.
I'm trying to copy the data present in an array of pointers to another one.
I have very few knowledge in C++, but some in higher level languages.
Here is a sample code of what I've achieved so far (simplified version):
#define MAX_ACTIVE_MODES 3
myStruct_t priorities1[MAX_ACTIVE_MODES];
myStruct_t *priorities2[MAX_ACTIVE_MODES];
for (unsigned short i = 0; i < MAX_ACTIVE_MODES; ++i) {
priorities2[i] = (myStruct_t*)malloc(sizeof(myStruct_t));
memcpy(priorities2[i], &priorities1[i], sizeof(myStruct_t));
}
// ...
delete[] *priorities2;
It's easier for me to have a non pointer var for priorities1 and have one for priorities2 because I'm passing it to a sort function.
When I search for solutions, there's never the case of type *var[] and I don't get why.
Even though your question is tagged c++, I assume that you are programming in C based on your use of malloc.
First you don't need to use memcpy to copy structs.
*priorities2[i] = priorities1[i];
should be equivalent to
memcpy(priorities2[i], &priorities1[i], sizeof(myStruct_t));
Second, you don't have to create copies of the elements in priorities1[]. Just have the pointers in priorities2[] point to the elements in priorities1[]:
for (size_t i = 0; i < MAX_ACTIVE_MODES; ++i)
{
priorities2[i] = &priorities1[i];
}
As long as you don't access priorities2 beyond the lifetime of priorities1, no malloc or free is needed.
I have this main function and i want to get an multidimensional array out of this to generate a graph instead of cout
int main(){
zoro z;
std:ifstream k("ggg.grf");
z.getfromstream(k);
for(int i =0 ; i < z.nnodes; i++){
edge_iteratore s = z.begin(i);
while(s != z.end(i)){
std:cout << "(" << (*s).height << "," << (*s).weight << ")" << std::endl;
++s;
}
}
return 0;
}
I' trying to get std::out to a function to generate a multidimensional array
so i have implemented this function to get an array,
int createarr(height,width){
int** ary = new int*[height];
for(int i = 0; i < height; ++i)
ary[i] = new int[weight];
}
but nothing works, how can i return an multidimensional array to use it in another function call instead of outputting it to the screen.
If height and weight are constexpr values you know at compile time, declare std::array<<std::array<int>, weight>, height>. This gets you locality of reference. If they are values you compute at runtime or that could vary, use vector<vector<int>>(height) and initialize each row. Then the compiler takes care of freeing the memory for you. If only one is fixed, you can also do a vector of arrays or an array of vectors.
It’s unfortunate that, because of the legacy char** argv interface of main(), every beginning C and C++ programmer thinks that’s how you do a two-dimensional array. A ragged array like that is almost never what you really want. But if you do, use std::vector to manage the memory for you.
The problem with your createarr() as written is that it doesn’t return any array pointer, but RAII is more likely what you want. And if you do have a sparse matrix that would benefit from raggedness, you can use a format like Compressed Sparse Row.
You need to return a pointer to the created array.
But you'll need to somehow deal with the fact that this is dynamically allocated memory, ie, you need to release it when you're done.
And you'll need to somehow encapsulate the dimensions too, which then means it needs to be a struct.
When you finally get tired of dealing with memory leaks, and understand how pointers work, use std::vector like the other guy said.
In the meantime, don't try to implement complicated algorithms in C without understanding the basics first. Brush up hard on how pointers and arrays actually work, first.
I am using the CUDD package for BDDs manipulation.
I want to make a copy for a big data structure in it that is called the DdManager.
The problem is : this data structure has so many pointers inside it , so when I make a direct copy it is a "shallow" copy(as some use the term) i.e. : the pointers in the new copy point to the same places pointed to by the original copy , so when I change in anyone of them I also change in the other which is undesirable ....
Trying to make a copy function by hand is not feasible because the data structure is really big and very detailed with many pointer to other complex structures also !!!
I have tried the vector solutions described here but I did not get the expected result because there are many nested structures and pointers and I want a completely new copy.
Here is a code sample of what I want to do :
#include <iostream>
#include <cstdlib>
#include <string.h>
#include <vector>
using namespace std;
struct n1
{
int a;
char *b;
};
struct n2
{
int **c;
struct n1 *xyz;
};
typedef struct
{
vector<struct n2> x;
}X;
int main()
{
struct n2 s1;
s1.xyz = (struct n1*)malloc(sizeof(struct n1));
s1.xyz->a = 3;
s1.xyz->b = (char*)malloc(5);
s1.xyz->b[0] = '\0';
strcat(s1.xyz->b,"Mina");
s1.c = (int**)malloc(5 * sizeof(int*));
for(int i = 0; i < 5; i++)
s1.c[i] = (int*)malloc(5 * sizeof(int));
for(int i = 0; i < 5; i++)
for(int j = 0 ; j < 5 ; j++)
s1.c[i][j] = i + j;
X struct1,struct2;
vector<struct n2>::iterator it;
it = struct1.x.begin();
it = struct1.x.insert(it,s1);
it = struct2.x.begin();
it = struct2.x.insert(it,struct1.x[0]);
cout<<"struct2.x[0].c[1][2] = "<<struct2.x[0].c[1][2] <<" !"<<endl; // This is equal to 3
(struct2.x[0].c[1][2])++; //Now it becomes 4
cout<<"struct2.x[0].c[1][2] = "<<struct2.x[0].c[2][2] <<" !"<<endl; //This will print 4
cout<<"s1.c[1][2] "<< s1.c[1][2]<<" !"<<endl; // This will also print 4 ... that's the wrong thing
return 0;
}
Despite other saying that you have to
make a copy function by hand
...to solve this, I think that's the wrong approach for you. Here's why, and here's a suggestion.
You're trying to create a copy of a CUDD ddManager object, which is an integral part of the complex CUDD library. CUDD internally uses reference counts for some objects (which might help you here...) but the ddManager object effectively represents an entire instance of the library, and I've no ideas how the reference counts would work across instances.
The CUDD library and it's associated C++ wrapper doesn't seem to provide the necessary copy constructors for creating separate copies of the ddManager, and to add these would probably involve serious effort, and detailed internal knowledge of a library that you are just trying to use as a client. While it's possible to do this, it's complex thing to do.
Instead, I'd look at trying to write out the current BDD to a file/stream/whatever, and then read it back into a new instance of a ddManager. There's a library called dddmp that should help you with this.
I'd also recommend that the C++ wrapper was modified to make the ddManager class non-copyable.
"Trying to make a copy function by hand is not feasible because the data structure is really big and very detailed with many pointer to other complex structures also !!! "
This is exactly what you have to do.
The objective approach means that you don't write one big do-it-all copy method. Instead, every object (structure) copies only itself, and then call it's sub-object copy methods, etc, etc until there is nothing more left to copy.
There is no such thing as "vector solution", vector is simply the smallest object with it's smallest copy method.
There is no difference between struct and class, so just write them copy methods.
Only you know the structure of your data, so you're the only One who can save the humankind (or copy this data).
I have this snippet of code which I am considering to simplfy:
if (numberOfResults > 1)
{
trackResult_ = new TrackResult[numberOfResults];
for (int i=0; i < numberOfResults; i++)
{
// Make a deep copy
TrackResult tempResult = result[i];
TrackResult * clone = new TrackResult(tempResult);
trackResult_[i] = *clone;
}
storeJointResults(trackResult_, numberOfResults);
}
else
{
trackResult_ = new TrackResult(*result);
}
(I have 'no choice' but to use a simple dynamic array here. Vectors are deemed 'too complicated' at my workplace)
I am wondering if I can get away with
// even if we just have one result, we init an array size of one
trackResult_ = new TrackResult[numberOfResults];
However, I have in several points check for the number of results and act accordingly
if (numberOfResults_ == 1)
{
velocity = trackResult_.velocity;
}
Would those code still work? If not, why?
The array of size 1 does not need to be a special case.
When you allocate a dynamic array you are given a pointer to the first element. If the array is of size 1, this is pretty much indistinguishable from just having allocated a single instance of the object.
Your special case usage would work if you changed the . to an ->
However I'd recommend not special-casing it and just use trackResult_[0].velocity
No, you need to ensure you match the correct scalar delete or array delete[] depending on whether you say new TrackResult[n]; or new TrackResult;.
Also, this leaks memory for each loop iteration:
TrackResult tempResult = result[i];
TrackResult * clone = new TrackResult(tempResult);
TrackResult_[i] = *clone;
How are vectors too complicated? If anything, the simplify your code.
I agree with Alex, using the . operator on a pointer is not my recommended style either, so those other points ought to be changed anyhow, and thus not discourage you from simplifying the piece of code you mention.