-1

我正在尝试完成 C 书籍中的练习(“Sam 在 21 天内自学 C”,第 18 章,练习 7)。

我的挑战是我无法理解为什么 void 指针指向的类型 double 变量数组的值会意外更改,但我指向的其他数据类型的值却按预期显示。

在下面的代码中,我调用了一个函数,该函数返回一个指向任何数据类型数组的 void 指针。main() 函数然后打印用户选择的数组的值。这个程序看起来很完美,除了由 void 指针分配的 double 类型数组的第二个元素的类型 double 值。由于某种我不知道的原因,第二个双精度类型变量的值,通过递增 main() 中的指针指向,意外地更改为不同数量的未知来源(可能在内存中的某个地方)。

我搜索了堆栈溢出和其他互联网资源以了解这一挑战的根本原因,但我没有找到解决方案,仍然不明白为什么会发生这种情况。请帮助我理解这一点。在我的编辑器中,出现问题的代码行是第 63 行,我尝试在其中打印预期值:

printf("Lowest value is %f\n\n", *((double *)ptr)); 

先感谢您。

这是代码片段:

/* function definition */
void *function(void *x, char type, int size);

/* array definitions */
int array1[] = {100, 200, 300, 400};
double array2[] = {10, 20, 30, 40, 50};
float array3[] = {1.2, 3.5, 35.2, 93};
long array4[] ={2034, 293049, 2039402, 394038};

/* variable definitions */
void *ptr;
char type;
int elements;

int main()
{
    printf("Which data type array do you want to find the largest and smallest");
    printf("values of?\n");
    printf("Options:\ni = int\nd = double\nf = float\nl = long\n\n x or X to exit\n");
    printf("Enter your selection: ");
    scanf("%c", &type);

    switch(type)
    {
        case 'i':
        {
            printf("\nYou selected: type int:\n");
            elements = sizeof(array1) / sizeof(int);
            ptr = malloc(sizeof(int) * 2);
            ptr = function(array1, type, elements);
            printf("\naddress of value pointed to by ptr = %u", (unsigned)ptr);
            printf("\nHighest value is %d\n", *((int *)ptr));
            ptr = ptr + sizeof(int);
            printf("\naddress of value pointed to by ptr = %u\n",     (unsigned)ptr);
            printf("Lowest value is %d\n\n", *((int *)ptr));
            break;
        }
        ...
        default:
        {
            puts("Incorrect input\n");
            break;
        }
    }
    return 0;
}

void *function(void *x, char type, int size)
{
    void *ptr[2];
    int count = 0;

    switch(type)
    {
        case 'i':
        {
            int high = ((int *)x)[0];
            printf("\nvalue of void *x = %d\n", high);
            int low = ((int *)x)[1];
            int array[2];
            for (count = 0; count < size; count++)          
            {
                if(((int *)x)[count] > high)
                    high = ((int *)x)[count];
                else if(((int *)x)[count] < low)
                    low =  ((int *)x)[count];
            }
            array[0] = high;
            array[1] = low;

            ptr[0] = malloc(sizeof(int)*2);
            ptr[0] = &array[0];
            ptr[1] = malloc(sizeof(int)*2);
            ptr[1] = &array[1];

            printf("\nWithin function:\n");
            printf("address of array = %lu\n", (long unsigned)array);
            printf("address of array[0] = %lu\n", (long unsigned)&array[0]);
            printf("address of array[1] = %lu\n", (long unsigned)&array[1]);

            printf("\nvalue of array[0] = %d", array[0]);
            printf("\nvalue of array[1] = %d\n", array[1]);         
            printf("\nvalue of ptr[0] = %d", *(int *)ptr[0]);
            printf("\nvalue of ptr[1] = %d\n", *(int  *)ptr[1]);            

            break;
        }
        ...
    }
    return *ptr;
}
4

2 回答 2

4

这至少是您问题的一部分:

    ptr[0] = malloc(sizeof(double)*2);
    ptr[0] = &array[0];
    ptr[1] = malloc(sizeof(double)*2);
    ptr[1] = &array[1];

您分配了一些内存,然后立即泄漏它。array是一个局部变量,所以ptr返回后指向垃圾。这可以解释为什么你的 print 语句在函数内部看起来是正确的,然后在你离开函数之后又是错误的。

其他类型的代码块中存在相同的问题。

于 2013-11-08T17:41:03.970 回答
0

您的程序行为未定义。您正在使用%u错误的说明符打印所有指针值。您应该使用%p说明符来打印指针值。

 printf("\naddress of value pointed to by ptr = %p", (void *)ptr);
于 2013-11-08T17:46:37.447 回答