Getting the values in an array into a pointer

Pages: 12
I have an array of values stored in p, then I try to copy the values into array, and later on I want to store the value from array into another_p.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

using namespace std;

long int *generate_random_vector();

int main()
{
     long int *p;
     long int *another_p;
     long int *array = new long int [n];//n will be obtained after reading 
                                        //from a file
     p = generate_random_vector();//generate_random_vector gives n
                                  //numbers of values to *p
     for (int i = 0; i < n; i++)
     {
          array[i] = p[i];
          another_p[i] = array[i];
     }
     
     return 0;
}


Is the code correct? Or am I using the pointers wrongly? I'm asking because my code didn't have SIGTRAP problem until I added these, so I was hoping someone could point out where am I doing wrongly.
Last edited on
You also need
long int *another_p = new long int [n];

If you used vectors, it would be so much simpler.
1
2
3
4
5
6
7
8
9
vector<long int> generate_random_vector();

...


     vector<long int> p = generate_random_vector();
     vector<long int> another_p = p;
     vector<long int> array = p;

Hi salem c,

There's a lot of parts in my code that uses the p, so I have to change a lot of variables into vector which I tried doing it earlier just now, but couldn't get the file to compile, so I was forced to use this method instead of vectors.

long int *another_p = new long int [n];
So p doesn't need it?
Is the code correct?

Obviously not. What is n and where does it come from?


1
2
     p = generate_random_vector();//generate_random_vector gives n
                                  //numbers of values to *p 

Rather hard to see how generate_random_vector() knows what n is.


So p doesn't need it?
What is "it"?



You should aim to supply "the minimum runnable code that reproduces the problem". You haven't given enough code to phrase a sensible question.
Last edited on
Hi lastchance,

I mentioned in line 11 and 12 that n can be obtained from reading a file, I've not given the whole code because generate_random_vector needs to call another function, and that function needs to call another function and so on, so the code I posted is indeed not runnable, but in my opinion sums up the things required to answer my question, also there will be other function calls in between the code I've posted, which will change the value of p, and that's why I want to store the value in another variable.

My "it" means having long int *p = new long int[n];
If dynamic memory is allocated within generate_random_vector() then you don't (in fact, you definitely shouldn't) allocate it again in main().


but in my opinion sums up the things required to answer my question
Our opinions differ.
Last edited on
I have to change a lot of variables into vector which I tried doing it earlier just now, but couldn't get the file to compile, so I was forced to use this method instead of vectors.

How about: solve the problem with vectors first.

How about:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <random>
#include <vector>

int main()
{
  std::default_random_engine generator;
  std::uniform_int_distribution<int> distribution( 1, 6 );

  size_t n {};
  std::cin >> n;
  std::vector<int> p( n );
  for ( int& x : p ) {
    x = distribution(generator);
  }

  std::vector<int> array = p;
  for ( int x : array ) std::cout << x << '\n';
}
Hi lastchance,
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
long int *generate_random_vector(long int n)
{

    /*    
    FUNCTION:      generates a random vector
    INPUT:         vector dimension
    OUTPUT:        returns pointer to vector, free memory when vector is not needed anymore
    (SIDE)EFFECTS: none
    */


    long int  i, j, help;
    long int  *v;
    srand(time(0));
    long int seed=rand();

    v = new long int[ n ];

    for ( i = 0 ; i < n; i++ )
    {
        v[i] = i;
    }

    for ( i = 0 ; i < n-1 ; i++)
    {
        j = (long int) ( ran01( &seed ) * (n - i));
        assert( i + j < n );
        help = v[i];
        v[i] = v[i+j];
        v[i+j] = help;
    }
    return v;
}


The line v = new long int [n]; means allocating a dynamic memory right? So I shouldn't do it again in the main function and I should be going to vectors instead, is that right? As I replied salem c, I've tried using vectors but couldn't get the file working, should I post the code I tried with vectors here?
The line v = new long int [n]; means allocating a dynamic memory right?

Correct. So, if you return the pointer to that memory it doesn't need allocating again.

There are times when dynamic allocation of memory are good. But this isn't one of them.

I should use vectors.
Hi keskiverto,

I've tried using vectors, but not the way you show (which I couldn't understand) because I've actually only took course of basic programming language which only covers up to arrays (pointers, vectors not included), so I can't really understand your code and for that I apologise.
Hi lastchance,

I've never used vectors before but this was my attempt earlier:
https://pastebin.com/d8FQPhEJ
Please kindly click the link to have a look, I got it to compile but it cannot complete the code, it stopped after finish reading from the file so I switched to using the code I posted in the question.
Yeah, it might be more trouble than it's worth to shoehorn vectors into a mass of code already using pointers all over the place.

> long int *another_p = new long int [n];
Should be all you need to make another copy of the array you dynamically created in the first instance.
Your first post:
1
2
3
long int *generate_random_vector();
long int *p;
p = generate_random_vector(); //generate_random_vector gives n 

Later:
1
2
3
long int *generate_random_vector(long int n) {
  // ...
}

Misleading. These are two different functions:
1
2
long int *generate_random_vector();
long int *generate_random_vector(long int);


I don't know what the ran01() is but I guess that it returns a random float from 0.0 .. 1.0
It is used in a loop that looks like shuffe. Overall, there are values {0, 1, 2, .. n-1} and their order is random.

Lets do that with C++:
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
#include <iostream>
#include <vector>       // std::vector
#include <numeric>      // std::iota
#include <algorithm>    // std::shuffle
#include <random>       // std::default_random_engine
#include <chrono>       // std::chrono::system_clock

std::vector<long int> generate_random_vector( long int n ) {
  std::vector<long int> v( n ); // array with n elements
  std::iota( v.begin(), v.end(), 0 ); // like the v[i] = i; loop

  // obtain a time-based seed and randomize order of values:
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  std::shuffle( v.begin(), v.end(), std::default_random_engine(seed) );

  return v;
}

int main() {
  std::vector<long int> p = generate_random_vector( 13 );

  for ( long int x : p ) {
    std::cout << ' ' << x;
  }
  std::cout << '\n';
}


Vector behaves like array (except when it behaves better).
1
2
3
4
5
6
7
8
long int* v = new long int[ n ];
// use v
delete [] v;

// VS
std::vector<long int> v( n );
// use v
// vector handles the deletion 

The "use v" is usually identical between the two.


The for ( int x : array ) std::cout << x << '\n'; is just a for loop with range-syntax that was added by C++11. It has been important part of "basic programming language" for 9 years now.
Hi salem c,

The code works fine after I added that line, however only in release, if I run the debugger it still shows SIGTRAP, any idea why?
Hi keskiverto,

Sorry they were the same functions, I forgot to remove the argument, since I had n as a global variable.

There are so many functions for vector and they prove to be much shorter than the code I have! Thanks for the code, however I have a question regarding this line unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();, since I have using namespace std;, will it become chrono::system_clock::now().time_since_epoch().count();? Or something even simpler?

Wow looks like my course I took in my university is much more basic than I thought, I was never taught about range-syntax.
Wow looks like my course I took in my university is much more basic than I thought, I was never taught about range-syntax.

Schools tend to lag behind by a distressing amount. They stick to old material and books and professors who have not kept up with changes. This makes sense when its the bleeding edge (like c++ 2020 changes, don't expect to see them in school before you graduate) but 2017 and 2011 changes are really a bit much to still be making excuses for not teaching. Ranged for loops are 2011 changes... 9 years... Use them, make your prof see them and acknowledge them at least.
Last edited on
Well I took your pastebin code and put the dynamic allocation back in.

Then compiled and saw this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ g++ -Wall -g foo.cpp
foo.cpp: In function ‘int main()’:
foo.cpp:39:14: warning: variable ‘initial_eval’ set but not used [-Wunused-but-set-variable]
     long int initial_eval;
              ^
foo.cpp:47:14: warning: unused variable ‘best_eval’ [-Wunused-variable]
     long int best_eval;
              ^
foo.cpp:48:14: warning: unused variable ‘improvement’ [-Wunused-variable]
     long int improvement;
              ^
foo.cpp: In function ‘void first_2_opt_symmetric()’:
foo.cpp:327:14: warning: variable ‘improve_item’ set but not used [-Wunused-but-set-variable]
     long int improve_item = 0;
              ^
foo.cpp: In function ‘void perturbation(long int)’:
foo.cpp:401:21: warning: ‘hold_value’ may be used uninitialized in this function [-Wmaybe-uninitialized]
         hold_value[i] = p[i];               //initialize hold_value with the same value from local search/*
                     ^

The only disaster waiting to happen here is your uninitialised pointer.
That fixed, it runs fine.


<<< snipped >>>
current best eval = 590
620
current best eval = 590

 Vector after local search = 9 1 8 2 5 0 10 6 4 3 11 7 


current best eval = 590
 Vector p = 9 1 8 2 5 0 10 6 4 3 11 7 

iteration 4th = 10000 

current best eval = 590

current best eval = 590
ILS best vector = 9 1 8 2 5 0 10 6 4 3 11 7 


It does however leak memory like a sieve, but that's easy enough to fix by finding a few places to put in appropriate delete[] calls.
==8822==
==8822== HEAP SUMMARY:
==8822== in use at exit: 1,035,392 bytes in 10,029 blocks
==8822== total heap usage: 20,032 allocs, 10,003 frees, 2,005,160 bytes allocated
==8822==
==8822== LEAK SUMMARY:
==8822== definitely lost: 960,096 bytes in 10,001 blocks
==8822== indirectly lost: 0 bytes in 0 blocks
==8822== possibly lost: 0 bytes in 0 blocks
==8822== still reachable: 75,296 bytes in 28 blocks
==8822== suppressed: 0 bytes in 0 blocks
==8822== Rerun with --leak-check=full to see details of leaked memory
==8822==
==8822== For counts of detected and suppressed errors, rerun with: -v
==8822== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)






Hi salem c,

Thanks for showing the errors, I sure hope I know how to get these. However, I'm sorry I don't know which of my pointers are not initialised and are causing problem.

However, I do have an updated code, seemingly running without problem but just want to be sure, can you teach me how to get those things you got?

Here's the updated code just in case:
https://pastebin.com/gCTLMiEN
if you are going to write pointer code:
when you make a pointer, initialize it to null if you did not set it to some valid address.

example:
char *cp = nullptr;
char *c = &x;

and every time you delete one, all null it:
delete[] foo;
foo = nullptr;

those two things will save you a lot of grief as you learn this stuff. Make them a habit.
> INT_MAX
You need
#include <climits>

Then this, what is n?
1
2
3
4
5
    long int n;
...
	ILS_best_p = new long int[n];
...
    infile >> n;



This won't fix any memory leaks either, coming as they do after return.
1
2
3
4
5
6
7
    return 0;
    delete [] ILS_best_p;
    delete [] matrix;
    delete [] v;
    delete [] x;
    delete [] hold_value;
    delete [] chosen;


Try this -> https://pastebin.com/14smEQXc
Last edited on
Pages: 12