[英]C program printing garbage values
我正在尝试创建一个数组并为其分配值。 虽然我可以正确分配值,但无法检索这些值,也不知道为什么。
这是代码片段的一部分。
void *arr = (void *)(malloc(sizeof(void *) * 5));
int i = 0;
for(i = 0; i < 5; i++) {
*(int *)(arr+i) = initial[i];
printf("Value of array: %d\n", *(int *)(arr+i));
}
for(i = 0; i < 5; i++) {
printf("Pushing: %d\n", *(int *)(arr+i));
DArray_push(result, (arr+i));
}
该程序的输出是
Value of array: 4
Value of array: 1
Value of array: 3
Value of array: 2
Value of array: 0
Pushing: 33751300
Pushing: 131841
Pushing: 515
Pushing: 2
Pushing: 0
为什么我的程序能够正确接受值,但是在以后尝试检索它们时却打印出垃圾值?
打开警告。 (arr+i)
未定义(您不能添加到void指针,并且只能在添加后执行强制转换)。 您会看到未定义的行为。
您可以进一步分配指针大小的东西,但将其视为int
(更多未定义的行为)。
为什么不写:
int *arr = malloc(sizeof(int) * 5);
int i = 0;
for(i = 0; i < 5; i++) {
arr[i] = initial[i];
printf("Value of array: %d\n", arr[i]);
}
for(i = 0; i < 5; i++) {
printf("Pushing: %d\n", arr[i]);
}
Pushing: 33751300 = 4 + 1 * 256 + 3 * 256 * 256 + 2 * 256 * 256 * 256
Pushing: 131841 = 1 + 3 * 256 + 2 * 256 * 256
Pushing: 515 = 3 + 2 * 256
Pushing: 2
Pushing: 0
该部分已经是错误的,但是在大多数32或64位编译器上仍然可以正常工作: sizeof(void *)
。 仅因为这至少在这些平台上具有int
的大小。
*(int *)(arr+i)
这是实际问题。 它没有访问下一个整数,而是访问了一个空指针可寻址的下一个地址,该指针通常是一个字节。 访问下一个整数将等效于此:
*(int *)(arr + i*sizeof(int))
或更容易阅读:
*( ((int *)arr) + i)
请记住,将指针增加一个偏移量不会添加到原始内存地址,但这取决于指针类型。
这里的重点是指针的算法。 当我们将值加1时,不同类型的指针就不会一样。 因此,让我们看一个例子:
(int *)p + 1 // it's moving 4 bytes
(void *)p + 1 // it's moving 1 byte in my compiler, void * is a generic type
在您的示例中,我们知道我们正在使用整数,因此在进行任何操作之前,我们需要告诉编译器将泛型指针转换为适当的类型。
尝试执行以下代码以了解我要说的内容:
#include <stdio.h>
#include <stdlib.h>
void main() {
int initial[] = {100, 101, 102, 103, 104};
void *arr = (void *)(malloc(sizeof(void *) * 5));
int i = 0;
for (i = 0; i < 5; i++) {
printf("%p\t%p\n", arr + i, ((int *)arr) + i);
}
for(i = 0; i < 5; i++) {
*(((int *)arr)+i) = initial[i];
printf("Value of array: %d\n", *(((int *)arr)+i));
}
for(i = 0; i < 5; i++) {
printf("Pushing: %d\n", *(((int *)arr)+i));
}
}
我找到了一些资源来帮助您:
https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html
问题是您不重置arr指针。 因此,在第二个循环中,您实际上是在初始数组之后打印值。
您需要创建一个变量来遍历数组。
void *p = arr;
然后使用它遍历数组。 并在第二个循环之前再次。
此外,请勿强制转换malloc函数调用的返回值(即使将其强制转换为void指针(它是malloc的实际返回类型)也是如此)。
编辑:您实际上不更改arr的值。 我的错。
首先,将malloc转换为void并使用sizeof void是毫无意义的。
假设initial[]
是另一个数组,则解决方法是:
#include <stdio.h>
#include <stdlib.h>
int initial[] = {10, 20, 30, 40, 50};
int main()
{
//allocate memory for 5 integers
int* arr = malloc(sizeof(int) * 5);
//loop over and copy from inital to arr
int i = 0;
for(i = 0; i < 5; i++) {
arr[i] = initial[i];
printf("Value of array: %d\n", arr[i]);
}
//pointer to first element of arr
int* arrPointer = arr;
for(i = 0; i < 5; i++) {
printf("Pushing: %d\n", *arrPointer);
//DArray_push(result, (*arrPointer));
//increment the arrPointer
arrPointer++;
}
//reset pointer if needed later...
arrPointer = arr;
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.