1

I use Visual Studio 2012. I've created my own function which works like sprintf(&a).

And i need to resolve problem: how do I swap two specific pointer elements?

Here is my code:

 #include <iostream>
 #include <stdio.h>
 #include <vector>

 using namespace std;

 void swap_spec(vector<int>* a, vector<int>* b)
 {
     vector<int>* tmp = NULL;

     *tmp = *a;

     *a = *b;
     *b = *tmp;

 }

 int main()
 {
     vector<int> test(4);

     test[0] = 5;
     test[1] = 4;
     test[2] = 3;
     test[3] = 2;

     swap_spec(*test[0], *test[1]);
     printf("%d %d", test[0], test[1]);

     return 0;
 }

I got an error:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

What is wrong? What i should change?

Spook
  • 25,318
  • 18
  • 90
  • 167
Jan Czarny
  • 916
  • 1
  • 11
  • 29
  • 6
    `vector* tmp = NULL; *tmp = *a;` what do you think this does? Especially the `*tmp` part? – Luchian Grigore Jun 10 '13 at 04:16
  • 3
    Your `swap_spec()` function expects pointers to vectors, but you pass.... something else. I am not even sure what you intended to pass. Looks like the you tried passing pointers to individual elements of the vector. – jogojapan Jun 10 '13 at 04:17
  • What's wrong with `std::swap`? – chris Jun 10 '13 at 04:18
  • @chris -> swap(&abc[0], &abc[1]); a lot of errors : ) swap(abc[0], abc[1]); -> segment fault – Jan Czarny Jun 10 '13 at 04:19
  • @Luchian Grigore vector* tmp = NULL; -> avoid compilator Warning unused tmp; – Jan Czarny Jun 10 '13 at 04:20
  • @JanCzarny, You need to `#include ` and `std::swap(test[0], test[1]);`. Seriously, that's not a good reason to create an inferior version of it. – chris Jun 10 '13 at 04:21
  • @chris -> way without pointers is not good. Because -> i need pointers in function who -> sort my vector and return array (via mod memory) – Jan Czarny Jun 10 '13 at 04:23
  • @chris -> using swap on pointer -> we got segmentfaul :/ – Jan Czarny Jun 10 '13 at 04:32
  • Just out of idle curiosity - how many times is the constructor/copy operator called in the swap function? – Ed Heal Jun 10 '13 at 04:34
  • @JanCzarny If all you want to do is swap pointers, why are you dereferencing them? Also, `std::swap` works just fine for pointers too. – Praetorian Jun 10 '13 at 04:35

5 Answers5

3

I am unsure as to what you are trying to do, but I am going to guess you are trying to swap two values in a vector. As your comments have said, using the swap would work, but I think you are confused as to what your code actually does. Let's go step by step here:

 vector<int> test(4);

    test[0] = 5;
    test[1] = 4;
    test[2] = 3;
    test[3] = 2;

swap_spec(*test[0], *test[1]); // *test[0] is the same as *(test[0])

When you perform *test[0], this is the same as *(test[0]). This means to dereference/look at the value in memory address test[0], which is 5. That memory address is inaccessible for you, so it will cause a seg fault.

Second problem:

void swap_spec(vector<int>* a, vector<int>* b)
 {
     vector<int>* tmp = NULL;

     *tmp = *a; 

     *a = *b; // This says, get whatever vector is pointed at b, and copy it to the memory location variable a points to. 
     *b = *tmp;

 }

Since you are passing in pointers to vectors, what you're saying here is to swap the two vectors, not the values inside them. But when you call this with:

swap_spec(*test[0], *test[1]); 

The type of test[0] is an int, the type of *(test[0]) is a dereferenced int (which is a seg-fault, but supposedly another int type), but the parameter type is a vector * (a pointer to a vector), which is already inconsistent with the arguments you pass in. See how this is already wrong in multiple levels.

So given all those information, it looks like you are trying to swap two values in the vector. You can do this one of two ways. You can do this with pointers:

void swap_spec(int *a, int *b) {
    int tmp = *a;

    *a = *b; // Go to address location where variable a points to, and assign whatever value is at memory location where variable b points to
    *b = tmp;
}

swap_spec(&test[0], &test[1]); // Pass in address of where test[0] and test[1] points to
                               // Note that type of &test[0] is an int * (Consistent with parameter)

Or with references:

void swap_spec(int &a, int &b) {
    int tmp = a;

    a = b; // Since you are using references, this will actually modify test[0] at its memory location 
    b = tmp;
}

swap_spec(test[0], test[1]); // Since you are using references, you don't need to pass in the address.

The second way is the same as the standard library's swap (http://www.cplusplus.com/reference/algorithm/swap/). References are sometimes (or perhaps generally) favored because it produces cleaner code (less * operators used) and hence less confusion.

1

You declare your function to take pointers to vector<int>s as parameters but you then pass is something else. *test[1] is dereferencing test[1] which is the int 4. You are treating ints 4 and 5 as pointers which is problematic.

It is not entirely clear what you are trying to accomplish, but if you just want to swap two elements of a vector, why not something like:

#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;

void swap_spec(vector<int>  & a, size_t i, size_t j)
{
        int tmp;

        tmp = a[i];

        a[i] = a[j];
        a[j] = tmp;
}

int main()
{
        vector<int> test(4);

        test[0] = 5;
        test[1] = 4;
        test[2] = 3;
        test[3] = 2;

        printf("%d %d \n", test[0], test[1]);
        swap_spec(test, 0, 1);
        printf("%d %d \n", test[0], test[1]);

        return 0;
}
A.E. Drew
  • 2,097
  • 1
  • 16
  • 24
1

Alright, I think this should do you, but my C's a little rusty:

#include <iostream>
#include <stdio.h>
#include <vector>

 using namespace std;

 void swap_spec(int* a, int* b)
 {
     int tmp = NULL;

     tmp = *a;

     *a = *b;
     *b = tmp;

 }

 int main()
 {
     vector<int> test(4);

     test[0] = 5;
     test[1] = 4;
     test[2] = 3;
     test[3] = 2;

     swap_spec(&test[0], &test[1]);
     printf("%d %d", test[0], test[1]);

     return 0;
 }

What I have done here is "swap the values at two memory locations", and then passed in the locations of the first and second element of your vector.

Let's go over your code, see if we can't clear some of what's going on up:

void swap_spec(vector<int>* a, vector<int>* b)

This says: Give me two pointers to vectors storing ints. When you're dealing with the elements of a vector, you just pass around the type stored in the vector: in this case, int:

void swap_spec(int a, int b)

However, C/C++ are pass-by-value, which means the passed values would be copied, and then used locally - meaning, you could not effect the overal program environment by passing in the values.

You got this, which is why you passed in pointers.

Instead, you need to pass in pointers to the values:

void swap_spec(int* a, int* b)

Technically, you're passing-by-value a memory address. Anyway - This lets you interact with memory (and this variables, objects, etc) outside of the function, in the overal program.

swap_spec(*test[0], *test[1]);

This passes in the values stored at the memory locations stored in test[0], which is invalid, because it's five.

What you want is:

swap_spec(&test[0], &test[1]);

Which pass in the memory addresses of those values, which is what you wanted.

Narfanator
  • 5,595
  • 3
  • 39
  • 71
1

Suppose what you really want do to is to swap two specific pointer elements. Then there are few possible errors. First the vector you created is an integer array instead of an pointer vector:

vector<int> test(4);

Second, in your function interface, the types of your input parameters are in fact a pointer to an integer vector (which means you would like to swap two vectors, instead of two integer pointers).

void swap_spec(vector<int>* a, vector<int>* b)

Third, since your vector is an integer vector, applying the indirection Operator * will let you get an error (*a means give me the content stored in the memory location described in variable a).

swap_spec(*test[0], *test[1]);

The following is how to swap "two integer pointers":

#include <stdio.h>

 void swap_spec(int** a, int** b) // the function which swaps int pointers.
 {
    int** tmp;

    *tmp = *a;
    *a = *b;
    *b = *tmp;
 }

 int main()
 {
   int** test = new int*[4]; // create an array of int integers

   for (int i = 0; i < 4; ++i) {
     test[i] = new int;
   }

   *test[0] = 5;
   *test[1] = 4;
   *test[2] = 3;
   *test[3] = 2;

   printf("%d %d\n", *test[0], *test[1]);
   swap_spec(&test[0], &test[1]);         // pass their addresses instead
   printf("%d %d\n", *test[0], *test[1]);

   for (int i = 0; i < 4; ++i) {
     delete test[i];
   }
   delete[] test;
   return 0;
}

If what you would like to do is simply swapping two int elements in a vector, then std::swap() or the answers proposed by @Narfanator and @Spook should work.

keelar
  • 5,814
  • 7
  • 40
  • 79
1

I guess, that you want to swap elements inside the vectors, not the vectors themselves. So firstly, don't swap std::vector<int> *, but just int *.

Secondly, pointers are not needed here at all. Use a function:

void swap_spec(std::vector<int> & vec, int index1, int index2)
{
     int tmp = vec[index1];
     vec[index1] = vec[index2];
     vec[index2] = tmp;
}

Then call it like this:

swap_spec(test, 0, 1);
Spook
  • 25,318
  • 18
  • 90
  • 167