Dynamic memory allocation inside an object

Is there any problem if I create a dynamic array on the heap when calling this specific member function (initial(..) of the Combosorting class ) ?
Why it just outputs the very first element of each array ? i.e a[0] ,b[0]
? It is supposed to print out the whole final array !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  #include <iostream>
#include <algorithm>


class ComboSorting
{
    int sizeofa ;
    int sizeofb ;
public:


    void  initial(int* a ,int* b)  //passing two arrays into a member function of this class
    {
        sizeofa = sizeof(a)/sizeof(int);
        sizeofb = sizeof(b)/sizeof(int);
        int* p = new int[sizeofa + sizeofb];  //allocate dynamic memory when calling this function . ? wrong ? or ?

        std::copy(a,a + sizeofa , p);
        std::copy(b,b + sizeofb , p+sizeofa);

        Print(p);
    }  // This function concatenates two arrays into a single one ,and print the biggest array later



    void Print(int *arr) //the Print function to be called by the initial function
    {
        for (int i = 0 ; i < sizeofa + sizeofb ; i++ )
        {
            std::cout <<arr[i] << std::endl ;
        }
    }



};

int main()
{


    int a[]  = {9,2,3,4,5,5,6,4,3,2,1};
    int b[]  = {212,21,32,412,5,5};

    ComboSorting obj ;

    obj.initial(a,b);

    return 0 ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <algorithm>

void Print(int *arr ,int length ) //the Print function modified to be called by main()
{


    for (int i = 0 ; i < length ; i++ )
    {
        std::cout <<arr[i] << std::endl ;
    }
}

int main()
{

    //Why it works okay ,if I make everything inside main() ????
    int a[]  = {9,2,3,4,5,5,6,4,3,2,1};
    int b[]  = {212,21,32,412,5,5};

    int sizeofa ;
    int sizeofb ;
    sizeofa = sizeof(a)/sizeof(int);
    sizeofb = sizeof(b)/sizeof(int);
    int* p = new int[sizeofa + sizeofb];  //I guess here the problem is , but why ?
    std::copy(a,a + sizeofa, p);
    std::copy(b,b + sizeofb, p+sizeofa);

    Print(p,sizeofa+sizeofb);
    return 0 ;
}



//I tested that , even I make those code inside a normal function , not a member function , it still behaves the same as it is a member function of an object

//All I wanna do is to capsulate those code into a class , so to make everything neat . but why this problem occurs ? what's the difference between calling it from a normal function and calling it from the main() function?
Last edited on
closed account (E0p9LyTq)
The data members of your class are integers, not pointers to integers.

You'd be better off IMO using the C++ STL dynamic containers, such as vector<>, as the data members instead of trying to "roll your own" by using raw pointers. That can lead to errors and memory leaks all too easily.
Thanks for replying ,but even I use the vector , I still can't fix this problem :(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <algorithm>
#include <vector>


class Combo
{
    int FinalLength ; 

public:
    //****************Printing *****************************
    void Print(std::vector<int>& v)
    {
        for (size_t i =0 ; i < v.size() ; i++ )
        {
            std::cout << v[i] << std::endl ;
        }
    }

    //*******************Taking arrays and Printing a sorted vector we created ***8
    void Processing(int *a, int *b)
    {
        FinalLength = sizeof(a)/sizeof(a[0])+sizeof(b)/sizeof(b[0]); /*Error ! sizeof() ,doesn't work with the array being passed to this function ! */ 
        int* p =new int[FinalLength];

        std::copy(a,a+sizeof(a)/sizeof(a[0]),p);
        std::copy(b,b+sizeof(b)/sizeof(b[0]),p+sizeof(a)/sizeof(a[0]));

        //converting
        std::vector<int>vec(p,p+FinalLength);  //implementing the empty vector we created !
        //sorting
        sort( vec.begin(), vec.end() );
        vec.erase( unique( vec.begin(), vec.end() ), vec.end() );
        Print(vec);
    }

};

int main()
{
    //Why it works okay ,if I make everything inside main() ????
    int a[]  = {9,2,3,4,5,5,6,4,3,2,1};
    int b[]  = {212,21,32,412,5,5};

    Combo obj ;
    obj.Processing(a,b);

    return 0 ;
}
Last edited on
The problem is with getting the FinalLength. Sizeof doesn't work with dynamic arrays.
You can make your life much easier by not using arrays and pointers. Look how simple it can be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>


typedef std::vector<int> IntVector;

class Combo
{
  int FinalLength;

public:
  //****************Printing *****************************
  void Print (IntVector& v)
  {
    for (size_t i = 0; i < v.size (); i++)
    {
      std::cout << v[i] << std::endl;
    }
  }

  //*******************Taking vector and Printing a sorted vector we created ***
  void Processing (IntVector& a, IntVector& b)
  {
    IntVector merged;
    std::copy (a.begin (), a.end (), back_inserter (merged));
    std::copy (b.begin(), b.end(), back_inserter(merged));

    sort (merged.begin (), merged.end ());
    merged.erase (std::unique (merged.begin (), merged.end ()), merged.end ());
    Print (merged);
  }

};

int main ()
{
  IntVector a = { 9, 2, 3, 4, 5, 5, 6, 4, 3, 2, 1 };
  IntVector b = { 212, 21, 32, 412, 5, 5 };

  Combo obj;
  obj.Processing (a, b);
  system ("pause");
  return 0;
}
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <algorithm>

class ComboSorting
{
    int sizeofa ;
    int sizeofb ;
public:
    
    void  initial(int* a , int sizeA, int* b, int sizeB)  //passing two arrays into a member function of this class
    {
        sizeofa = sizeA;
        sizeofb = sizeB;
        int* p = new int[sizeofa + sizeofb];  //allocate dynamic memory when calling this function . ? wrong ? or ?

        std::copy(a,a + sizeofa , p);
        std::copy(b,b + sizeofb , p+sizeofa);

        Print(p);
    }  // This function concatenates two arrays into a single one ,and print the biggest array later
    
    void Print(int *arr) //the Print function to be called by the initial function
    {
        for (int i = 0 ; i < sizeofa + sizeofb ; i++ )
        {
            std::cout <<arr[i] << std::endl ;
        }
    }
};

int main()
{
    int a[]  = {9,2,3,4,5,5,6,4,3,2,1};
    int b[]  = {212,21,32,412,5,5};

    ComboSorting obj ;

    obj.initial(a,sizeof(a)/sizeof(int), b,sizeof(b)/sizeof(int));

    return 0 ;
}


9
2
3
4
5
5
6
4
3
2
1
212
21
32
412
5
5
Last edited on
@Thomas1965@kemort
Thank you guys for being so helpful ! I really appreciate it .
Here is the conclusion I summarize from your replies .
About passing arrays into a function
1.Convert arrays into vectors ,and pass them into a function .then sizes of the vectors will be calculated easily . (Convert & Pass) (Thomas)
2.Pass arrays' addresses (or names ) and the lengths of the arrays into a function (Pass 2 types of info of array ) (kemort)
Why did I fail ?
1. sizeof() doesn't work with arrays being passed into a function
2. sizeof() doesn't work with the pointer generated by the new keyword . it won't give you the valid array length on the heap pointed by this pointer .
New question:
Is it possible that I only pass the address of the arrays into a function and get the length of the arrays within that function ?
Last edited on
closed account (48T7M4Gy)
Arrays are always passed as a pointer to the first element so sizeof only calculates the sizeof of that pointer and not the size of all elements. A passed array doesn't implicitly "know " how many elements it has.
Is it possible that I only pass the address of the arrays into a function and get the length of the arrays within that function ?
It is possible when usIng templates:
1
2
3
4
5
  template<typename arr_type, const int size>
  inline int numof(const arr_type (&arr)[size])
  {
    return size;
  }
@sail - I have a bit of interest in the topic as well

@coder777 So aside from Templates (which I don't know yet), the only way to get a semi-reliable size reading from an array is something like...

1
2
3
4
5
6
7
8
int get_array_size(const int* p)
{
     const int* get_size = p;
     int count{0};
     while(*get_size++) ++count;
     get_size = nullptr; //I just do this out of habit to ensure it's not still pointing to p
     return count;
}


Which, while not only tedious and special-purpose (need a function for every type), seems like it would introduce its own problems, yes?
closed account (48T7M4Gy)
template<typename arr_type, const int size>

Does this extra level of abstraction overcome the basic problem of C-style arrays not implicitly "knowing" it's size?
Last edited on
Yawzheek wrote:
Which, while not only tedious and special-purpose (need a function for every type), seems like it would introduce its own problems, yes?
Yes, just pass the size of the array and/or store the size.


kemort wrote:
Does this extra level of abstraction overcome the basic problem of C-style arrays not implicitly "knowing" it's size?
Not quite sure whether I understand your question correctly. As much as I understand, both:

No:
Once the array is converted to a pointer this type of function cannot be applied.

Yes:
This type of function can maintain the size information as long as it is needed.
closed account (48T7M4Gy)
The point is if you pass a C-style array to a function then you must pass the size of the array along with the (effectively) pointer to the first element. There is no way of getting around it AFAIK, in answer to the sail456852's question .

Of course you can use a <vector>, <array> but they are not C-style arrays. "Knowing" their size is one of the strengths of STL containers. :)
@Yawzheek
I tested your function ,which turned out be false . It gave me wrong size
int get_array_size(const int* p)
{
const int* get_size = p; //create a local pointer which can't be changed
int count{0}; //create a variable to store counts
while(*get_size++) ++count; //This should produce error ,get_size is constant ,how can it be compiled ? I tested it ,no error when compiling .weird
get_size = nullptr; //I just do this out of habit to ensure it's not still pointing to p
return count;
}
@coder777
Thanks for offering this code snippet . It's so cool !!! I don' understand why it works ,but
I guess , when compiler creates a function from this template , It will derive the information it needs from the argument being passed into this function dynamically.(including the address and the size).so it works
Last edited on
closed account (48T7M4Gy)
The mind boggles at your interpretation. There is no mystery. There is no magic. The function/template hides the fact that you must pass the size one way or another, in this case by specifying size as follows.

template<typename arr_type, const int size>
Topic archived. No new replies allowed.