1

我使用 Visual Studio 2012。我创建了自己的函数,其工作方式类似于 sprintf(&a)。

我需要解决问题:如何交换两个特定的指针元素?

这是我的代码:

 #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;
 }

我收到一个错误:

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

怎么了?我应该改变什么?

4

5 回答 5

3

我不确定您要做什么,但我猜您正在尝试交换向量中的两个值。正如您的评论所说,使用交换会起作用,但我认为您对代码的实际作用感到困惑。让我们一步一步来:

 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])

当您执行 *test[0] 时,这与 *(test[0]) 相同。这意味着取消引用/查看内存地址 test[0] 中的值,即 5。您无法访问该内存地址,因此会导致段错误。

第二个问题:

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;

 }

由于您正在传递指向向量的指针,因此您在这里所说的是交换两个向量,而不是它们内部的值。但是当你用以下方式调用它时:

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

test[0] 的类型是 int,*(test[0]) 的类型是取消引用的 int(这是一个段错误,但应该是另一个 int 类型),但参数类型是向量 *(a指向向量的指针),这已经与您传入的参数不一致。看看这在多个级别上已经是错误的。

因此,鉴于所有这些信息,您似乎正在尝试交换向量中的两个值。您可以通过以下两种方式之一执行此操作。您可以使用指针执行此操作:

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)

或参考:

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.

第二种方式与标准库的swap相同(http://www.cplusplus.com/reference/algorithm/swap/)。引用有时(或可能普遍)受到青睐,因为它产生更清晰的代码(使用较少的 * 运算符)并因此减少混乱。

于 2013-06-10T05:04:29.170 回答
1

你声明你的函数将指向vector<int>s 的指针作为参数,但是你传递的是别的东西。 *test[1]正在取消引用test[1],即 int 4。您将 int 4 和 5 视为有问题的指针。

目前尚不完全清楚您要完成什么,但如果您只想交换向量的两个元素,为什么不这样做:

#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;
}
于 2013-06-10T04:35:39.827 回答
1

好吧,我认为这应该对你有用,但我的 C 有点生疏:

#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;
 }

我在这里所做的是“交换两个内存位置的值”,然后传入向量的第一个和第二个元素的位置。

让我们检查一下您的代码,看看我们是否无法清除一些正在发生的事情:

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

pointers这说:给我两个vectors storing ints。当您处理向量的元素时,您只需传递存储在向量中的类型:在这种情况下,int

void swap_spec(int a, int b)

但是,C/C++ 是按值传递的,这意味着传递的值将被复制,然后在本地使用——这意味着,您无法通过传递值来影响整个程序环境。

你明白了,这就是你传递指针的原因。

相反,您需要传入pointers to the values

void swap_spec(int* a, int* b)

从技术上讲,您正在按值传递内存地址。无论如何 - 这使您可以在整个程序中与函数外部的内存(以及此变量、对象等)进行交互。

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

这会传入存储在 中的内存位置的值test[0],这是无效的,因为它是 5。

你想要的是:

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

传入这些值的内存地址,这就是你想要的。

于 2013-06-10T04:39:36.607 回答
1

假设您真正想做的是交换两个特定的指针元素。然后几乎没有可能的错误。首先,您创建的向量是一个整数数组而不是指针向量:

vector<int> test(4);

其次,在您的函数接口中,输入参数的类型实际上是指向整数向量的指针(这意味着您希望交换两个向量,而不是两个整数指针)。

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

第三,由于你的向量是一个整数向量,应用间接运算符*会让你得到一个错误(*a意味着给我存储在变量中描述的内存位置的内容a)。

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

以下是如何交换“两个整数指针”:

#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;
}

如果您想做的只是交换向量中的两个 int 元素,那么std::swap()@Narfanator 和@Spook 提出的答案应该可以工作。

于 2013-06-10T04:40:53.040 回答
1

我想,您想交换向量内的元素,而不是向量本身。所以首先,不要交换std::vector<int> *,而只是int *

其次,这里根本不需要指针。使用一个函数:

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

然后像这样调用它:

swap_spec(test, 0, 1);
于 2013-06-10T04:43:53.547 回答