首页 > 解决方案 > 是否存在使用取消引用的指针在内存中交换 2 个值的边缘情况?

问题描述

我在 C 中编写了这个简单的函数来交换内存中 2 个地址中的值:

void pointersswap (int *ptr1, int *ptr2) 
{
    *ptr1 = *ptr1*(*ptr2);
    *ptr2 = *ptr1/(*ptr2);
    *ptr1 = *ptr1/(*ptr2);
}

有人告诉我,这个程序可能会遇到一个“边缘案例”。您可以假设输入是正确的(ptr1 和 ptr2 实际上保存地址值,并且这些地址指向有 2 个非 0 整数的内存)。数学总是检查,即使任何一个取消引用的指针包含一个负数,或者两者都是负数,或者分数。

作为参考,此代码不应有相同的问题/边缘情况:

void pointersswap (int *ptr1, int *ptr2) 
{
    int temp = *ptr1;
    *ptr1 = *ptr2;
    *ptr2 = temp;
}

我错过了什么?第一个功能真的有任何限制/边缘情况吗?

小澄清:假设没有信息溢出/丢失。

标签: cpointers

解决方案


首先,“表达式”like*ptr1/*ptr2不起作用,因为/*在 C 中被解释为注释的开头。

替换为 后/*/ *(至少)有两种情况下该功能不起作用:

  • 当乘法溢出时。
  • 当指向同一个变量的指针同时传递给a和时b
#include <stdio.h>

void pointersswap (int *ptr1, int *ptr2) 
{
    *ptr1 = *ptr1*(*ptr2);
    *ptr2 = *ptr1/ *ptr2;
    *ptr1 = *ptr1/ *ptr2;
}

int main(void) {
    int a, b;
    a = 999999; b = 888888;
    printf("before: a = %d, b = %d\n", a, b);
    pointersswap(&a, &b);
    printf("after ; a = %d, b = %d\n", a, b);

    a = 12345;
    printf("before: a = %d\n", a);
    pointersswap(&a, &a);
    printf("after : a = %d\n", a);
    return 0;
}

输出

before: a = 999999, b = 888888
after ; a = 891245, b = -192
before: a = 12345
after : a = 1

推荐阅读