标签: pointers

警告:算术中使用的'void*'类型的指针

我正在编写和读取内存映射中的寄存器,如下所示:

//READ
return *((volatile uint32_t *) ( map + offset ));

//WRITE
*((volatile uint32_t *) ( map + offset )) = value;
Run Code Online (Sandbox Code Playgroud)

但是编译器给了我这样的警告:

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
Run Code Online (Sandbox Code Playgroud)

如何更改我的代码以删除警告?我正在使用C++和Linux.

c++ pointers void-pointers pointer-arithmetic

13
推荐指数
2
解决办法
2万
查看次数

为什么我会"从指针转换为不同大小的整数"错误?

下面的行(纯c)在windows(win7 64位+代码块13 + mingw32)和debian(wheezy 32位+代码块10 + gcc)上干净地编译,但在kali(64位+代码块+ gcc)上引发警告.任何意见?我的意思是,为什么我会收到这个警告,虽然同一行编译没有窗口和debian上的任何警告?

void* foo(void *dst, ...) {
    // some code
    unsigned int blkLen = sizeof(int); // this line ok.
    unsigned int offset = (unsigned int) dst % blkLen; // warning here!
    // some code cont...
}
Run Code Online (Sandbox Code Playgroud)

codeblocks中的消息是:" error:从指针转换为不同大小的整数[-Werror = pointer-to-int-cast]"

注意:我的编译器选项是-std=c99 -Werror -save-temps(在所有三个系统上都相同).

编辑2:虽然我已经设法使用下面的预处理器行编译无警告,但@Keith Thompson(见下文)对此问题有一个关键点.所以,我最后的决定是使用uintptr_t将是一个更好的选择.

编辑1:谢谢大家的回复.正如所有回复所述,问题是32位与64位问题.我插入了以下预处理行:

#if __linux__   //  or #if __GNUC__
    #if __x86_64__ || __ppc64__
        #define ENVIRONMENT64
    #else
        #define ENVIRONMENT32
    #endif
#else …
Run Code Online (Sandbox Code Playgroud)

c gcc pointers

13
推荐指数
3
解决办法
5万
查看次数

为什么这种隐式转换(在不同的指针类型之间)有效?

我发现自己处于以下情况:

#include <stdio.h>

typedef struct T1 { int id; } T1;  
typedef struct T2 { int id; } T2;

void f(T1 *ptr) { printf("f called\n"); }

int main(void) 
{
    T2 obj; 
    T2 *ptr = &obj; 
    f(ptr); // shouldn't this be a compilation error ? 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,这是无效的C++,但在C中,程序打印 "f called".这有效吗?

编辑

(以防万一不清楚)如果"结构上"不同,程序仍然可以编译和运行T2,例如

typedef struct T2 { double cc[23]; } T2;
Run Code Online (Sandbox Code Playgroud)

c pointers implicit-conversion

13
推荐指数
2
解决办法
1276
查看次数

如果使用g ++,为什么std :: cout可以转换为void*?

为什么一个能投射出std::ostreamvoid指针?我不知道有任何这样的转换运算符std::ostream.代码如下

#include <iostream>

int main()
{
    void *p = std::cout; // why does this work? 
}
Run Code Online (Sandbox Code Playgroud)

我问这个问题,因为我已经看到new调用了一个放置操作符

Foo* pFoo = new (std::cerr) Foo;
Run Code Online (Sandbox Code Playgroud)

并且完全不知道为什么会写这样的东西.

PS:我正在使用或不使用g ++ 4.9.2进行编译-std=c++11.clang ++ 不接受代码.

PSS:发现由于所谓的"安全bool问题"(参见@ nicebyte的回答),在预C++ 11 void*中定义了一个转换运算符std::ostream,然后在C++ 11中将其删除.但是,我的代码使用g ++在C++ 11中编译得很好.更重要的是,clang ++拒绝它,无论我使用什么版本的标准,即使有-std=c++98,尽管我的理解是它应该接受,如果编译为pre-C++ 11.

c++ pointers ostream implicit-conversion

13
推荐指数
1
解决办法
349
查看次数

在C#中使用Cheat Engine中的指针

关于该计划

我有一个程序写入我正在试验的游戏的记忆.当我使用常规静态地址时,代码对我很有用,但出于某种原因,一旦找到工作指针,我似乎无法做到这一点.例如,我在指针扫描几次后在Cheat Engine中找到了这个:

在此输入图像描述

每次加载游戏并编辑值时,此地址都有效.问题是我不明白如何在我的程序中使用它.这是我尝试插入值的声明变量:

bool UnlimitedAmmo = false;
string AmmoPointer = "031B7324"; // <--- The address
int[] AmmoOffset = { 0x2c, 0x1e8, 0x3c8, 0x6d4, 0x508 }; // <--- It's pointers
int AmmoToFill = 1337; // <--- The Amount of ammo to give
Run Code Online (Sandbox Code Playgroud)

我传递这些变量如下:

MyMemory.ReadProcess = MyProcess[0];
MyMemory.Open();

int PointerAddress = HexToDec(AmmoPointer);
int[] PointerOffest = AmmoOffset;
int BytesWritten;
byte[] ValueToWrite = BitConverter.GetBytes(AmmoToFill);
string WrittenAddress = MyMemory.PointerWrite((IntPtr)PointerAddress, ValueToWrite, 
  PointerOffest, out BytesWritten);
MyMemory.CloseHandle();
Run Code Online (Sandbox Code Playgroud)

我曾经使用静态地址(对于不同的游戏),一旦插入地址和偏移量,我的代码工作正常.这次我很难过.任何帮助和解释都将深表感谢.提前致谢.

c# memory pointers cheat-engine

13
推荐指数
1
解决办法
5185
查看次数

为什么在C中使用指针?

我仍然想知道为什么在C中你不能简单地使用普通变量设置一些东西.变量本身是指向数据的指针,不是吗?那么为什么当你可以简单地使用原始变量时,指针指向变量中的数据呢?它是否可以访问所述变量中的特定位(或字节,我猜)?

我确信这是合乎逻辑的,但是我从来没有完全掌握这个概念,当阅读代码时*pointers总是把我抛弃.

c pointers

13
推荐指数
4
解决办法
6158
查看次数

不在C中转换指针会导致问题?

昨天我上课了,在某个时候讲师正在谈论C代码.他说:

在C中制作指针的目的是什么?唯一的目的是使编译器正确解释指针操作(例如,添加int指针将导致与添加char指针不同的偏移量).除此之外,没有区别:所有指针在内存中的表示方式相同,无论指针指向int值,char值,short值还是其他.因此,转换指针不会修改内存中的任何内容,它只会帮助程序员进行与其正在处理的指针类型更相关的操作.

但是,我已经阅读,特别是在Stack Overflow中,这不是100%真实.我已经读过,在一些奇怪的机器中,不同类型的指针可以以不同的方式存储在内存中.在这种情况下,如果将代码编译为此类机器,则不将指针更改为正确的类型可能会导致问题.

基本上,这是我正在谈论的那种代码.请考虑以下代码:

int* int_pointer;
char* char_pointer;
int_pointer = malloc(sizeof(int));
*int_pointer = 4;
Run Code Online (Sandbox Code Playgroud)

现在有两种选择:

1.

char_pointer = (char *)int_pointer;
Run Code Online (Sandbox Code Playgroud)

2.

char_pointer = int_pointer;
Run Code Online (Sandbox Code Playgroud)

案例2的代码可能成为一个问题?制作演员表(案例1)最终会改变内存中的指针格式(如果是的话,你能给出一个机器的例子吗?)?

谢谢

c pointers casting

13
推荐指数
2
解决办法
1599
查看次数

C中的MISRA增量

在调试一些嵌入式代码时,我遇到了类似这样的事情:

buffPtr = &a[5];
buffEndPtr = &a[10];

while (buffPtr != buffEndPtr) 
{ 
    *buffPtr = 0xFF; 
    buffPtr  = &buffPtr[1];         /*  MISRA improvement for: buffPtr++ */ 
}
Run Code Online (Sandbox Code Playgroud)

为什么这个结构会改进(*buffPtr)++?

c embedded pointers misra

13
推荐指数
3
解决办法
5438
查看次数

将非`void`指针转换为`uintptr_t`,反之亦然

有两个相关的C标准规则:

C99标准,6.3.2.3:

指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针.

而且7.20.1.4:

以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针: uintptr_t

这意味着,以下代码符合:

int *p = NULL;
void *q = (void*)p;
uintptr_t s = (uintptr_t)q;
Run Code Online (Sandbox Code Playgroud)

但它真的需要两步演员吗?如果执行以下操作,编译器是否会执行隐式中间转换:

int *p = NULL;
uintptr_t s = (uintptr_t)p;
Run Code Online (Sandbox Code Playgroud)

(好吧,它可能会出现在大多数编译器上,但我的问题是关于标准符合性)

c standards pointers casting

13
推荐指数
1
解决办法
4012
查看次数

传递可变大小的多维数组

我试图理解将多维数组传递给c中的函数的"最佳实践"(或实际上是任何实践).当然这取决于应用程序,因此我们考虑编写一个函数来打印可变大小的2D数组.特别是,我对如何printArry(__, int a, int b)在下面的代码中编写函数感兴趣.我省略了第一个参数,因为我不确定应该是什么.

void printArry(_____, int a, int b){
/* what goes here? */
}


int main(int argc, char** argv){

int a1=5;
int b1=6;
int a2=7;
int a2=8;

int arry1[a1][b1];
int arry2[a2][b2];

/* set values in arrays */

printArry(arry1, a1, b1);
printArry(arry2, a2, b2);

}
Run Code Online (Sandbox Code Playgroud)

c arrays pointers multidimensional-array variable-length-array

13
推荐指数
1
解决办法
1118
查看次数