标签: pointer-arithmetic

使用void指针指向数组

我只是试图使用一个指向整数数组的void指针,我试着看看我是否可以通过将数组转换回int来打印它.但它给了我一些随机价值.你能告诉我哪里出错了吗?

#include<stdio.h>
#include<stdlib.h>

int main(){
    int a[5];
    int x;
    int j;

    a[0]=1;
    a[1]=2;
    a[2]=3;
    a[3]=4;

    void *arr=a;

    for(j=0;j<4;j++){
        x = *(int *)(arr+j);
        printf("%d",x);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

133554432131072512
Run Code Online (Sandbox Code Playgroud)

为什么它没有固定数组的元素a []即1,2,3,4?

c pointers void-pointers pointer-arithmetic

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

增加数组错误指针的运算符?

我正在尝试一些非常简单的事情,应该很简单,但它不知何故让我感到烦恼......

我试图理解++对数组的影响,当被视为数组时被视为指针和指针.

所以,

int main()
{
    int a[4] = { 1, 4, 7, 9 };
    *a = 3;
    *(a+1) = 4;
    *++a = 4; //compiler error
}
Run Code Online (Sandbox Code Playgroud)

1:所以在*(a+1)=4我们设置[1] = 4; //快乐但是,当*++a = 4;我想要指针a增加一个因为++先于*然后*启动而我们使它等于4.但是这个代码不起作用......为什么会这样?

另一个问题:

int main()
{

    int* p = (int *)malloc(8);
    *p = 5;
    printf("%d", p[0]);

    *++p = 9; //now this works!
    printf("%d", p[1]); //garbage
    printf("%d", p[0]); //prints 9

}
Run Code Online (Sandbox Code Playgroud)

2:现在*++ p = 9; 工作得很好,但它的表现并不像数组.两个有什么不同?这只是递增p,并使其等于9.如果我打印p [0],它现在打印9,我看到虽然不能通过p [0]访问它,*(p-1)显示5还在那里.所以用[0]索引指针,它究竟指向哪里?发生了什么变化?

非常感谢所有专家!

c c++ arrays pointer-arithmetic dereference

5
推荐指数
1
解决办法
3844
查看次数

汇编指针算术LEA指令

LEA指令是否支持负位移?

mov rax, 1
lea rsi, [rsp - rax]
Run Code Online (Sandbox Code Playgroud)

当我在我的asm文件中使用上面的代码时,我得到了错误:

$ nasm -f macho64 test.asm
$ error: invalid effective address
Run Code Online (Sandbox Code Playgroud)

我知道我们可以在C中做这样的事情:

void foo(char *a, size_t b) {
    *(a - b) = 1;
}
Run Code Online (Sandbox Code Playgroud)

那我假设:

lea rsi, [rsp - rax]    
Run Code Online (Sandbox Code Playgroud)

将工作.

我还尝试使用以下命令查看GCC编译器的功能:

$ gcc -S foo.c // foo.c has the function foo(above) in it
Run Code Online (Sandbox Code Playgroud)

但是我的asm knowleage对我来说还不够理解GCC编译器的asm输出.

谁能解释原因:

lea rsi, [rsp - rax]    ;; invalid effective address
Run Code Online (Sandbox Code Playgroud)

不起作用.我正在使用它们来实现同样的目标:

;; assume rax has some positive number
neg rax    
lea rsi, [rsp + rax] …
Run Code Online (Sandbox Code Playgroud)

assembly pointer-arithmetic

5
推荐指数
1
解决办法
776
查看次数

如果我知道仅将使用现有元素,是否可以在数组开头之前传递指针?

我有一个代码,其中执行如下操作:

double computeSometing(const double * parameters)
{
  return useValues(parameters - 10); 
  // in this special case, useValues only uses values that are 
  // at least at parameters[0] or after
}
Run Code Online (Sandbox Code Playgroud)

这看起来很糟糕,但是仅在以下情况下才调用此代码:在这种情况下,我知道useValues在10号之前不会使用任何值(情况并非总是如此),因此所使用的所有值都是“ inside” parameters。那是不确定的行为吗?我知道它只能在我使用过的所有编译器/平台上运行,但这并没有定义它。

我这样做是为了避免将其内容复制parameters到具有10个以上元素的新数组中,因为此函数对性能敏感。

c++ arrays pointers pointer-arithmetic language-lawyer

5
推荐指数
1
解决办法
106
查看次数

这是否违反了严格的别名规则?

受到我对最近帖子的评论的启发:C get element on place without parenthesis,我想知道以下代码是否违反了严格的别名规则:

#include <stdio.h>

int main(void)
{
    int num[3] = { 1, 2, 3 };

    printf("num[1] = %d\n", *(int *)((char *)num + sizeof(int)));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我知道将类型转换为其他类型的指针取消引用char是违规行为,但在这里,原始指针的类型为int *。它在被强制转换为char *then后被取消引用int *

这是否违反了严格的别名规则?

c strict-aliasing pointer-arithmetic language-lawyer

5
推荐指数
1
解决办法
179
查看次数

指针算术规则中的“可能假设”是什么意思?

在标准的指针算术规范中 ( [expr.add]/4.2,我们有:

否则,如果P指向数组元素的阵列对象的xÑ元素([dcl.array]),则表达式P + JJ + P(其中,J具有值Ĵ)点到(可能-假想)阵列元件I + Jx如果0 ? 我 + j ? n并且表达式P - J指向(可能是假设的)数组元素i ? Ĵx,如果0?一世 ?? 名词

“可能-假设”在这里是什么意思?该段落已经将结果指针限制在数组范围内。好吧,包括最后一个插槽。它指的是这个吗?

c++ pointers pointer-arithmetic language-lawyer

5
推荐指数
1
解决办法
120
查看次数

为什么不建议在 C 中使用指针进行数组访问

我正在学习 C 编程,我在网上看到了本教程,其中指出您应该始终尽可能多地使用 [] 运算符而不是指针算法。

https://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html#dynamic

你可以使用指针算术(但一般不要)

考虑下面的 C 代码

int    *p_array;
p_array = (int *)malloc(sizeof(int)*50);

for(i=0; i < 50; i++) {
  p_array[i] = 0;
}
Run Code Online (Sandbox Code Playgroud)

使用如下代码的指针算术有什么区别(为什么不推荐)

int    *p_array;
p_array = (int *)malloc(sizeof(int)*50);      // allocate 50 ints

int *dptr = p_array;

for(i=0; i < 50; i++) {
  *dptr = 0;
  dptr++;
}
Run Code Online (Sandbox Code Playgroud)

在哪些情况下使用指针算法会导致软件出现问题?这是不好的做法还是缺乏经验的工程师可能不注意?

c arrays pointers pointer-arithmetic

5
推荐指数
1
解决办法
504
查看次数

减 1 与递减迭代器

“使用 end()-- 迭代到 std::vector 的最后一个元素”的可接受答案中@barry 指出:

请注意,如果 vector::iterator 只是 T* (这将是有效的),则上面的第一种形式是错误的。无论如何,后两者都有效,因此更可取。

参考他的代码:

std::vector<int>::iterator it = --container.end();
std::vector<int>::iterator it = container.end() - 1;
std::vector<int>::iterator it = std::prev(container.end());
Run Code Online (Sandbox Code Playgroud)

这一观点在评论中存在争议,但没有明确的解决方案。这就是我的问题:第一个和第二个之间的语义差异究竟是什么?对于除 之外的结构上的迭代器,答案会有所不同吗vector

c++ pointers iterator pointer-arithmetic undefined-behavior

5
推荐指数
1
解决办法
1057
查看次数

C/C++编译器如何区分常规二维数组和数组指针数组?

常规静态分配数组如下所示,可以使用以下公式进行访问:

const int N = 3;
const int M = 3;

int a1[N][M] = { {0,1,2}, {3,4,5}, {6,7,8} };

int x = a1[1][2]; // x = 5 
int y = *(a1+2+N*1); // y = 5, this is what [] operator is doing in the background
Run Code Online (Sandbox Code Playgroud)

数组是连续的内存区域。在动态数组分配的情况下看起来有所不同,而是有指向数组的指针数组:

int** a2 = new int*[N];
for (int i = 0; i < N; i++) 
   a2[i] = new int[M];

//Assignment of values as in previous example

int x = a2[1][2];
int y = *(*(a2+1))+2); // …
Run Code Online (Sandbox Code Playgroud)

c c++ pointer-arithmetic multidimensional-array implicit-conversion

5
推荐指数
1
解决办法
196
查看次数

无条件创建指向向量最后一个元素的指针合法吗?

我有以下 C++ 代码:

void bar(int&);
void baz();

void foo(std::vector<int>& v) {
    int* pointer_to_last = v.data() + (v.size() - 1);
    if (v.size() > 0 && *pointer_to_last == 42) {
        bar(*pointer_to_last);
    } else {
        baz();
    }
}
Run Code Online (Sandbox Code Playgroud)

我无条件创建一个指向向量最后一个元素的指针,但仅当向量不为空时才取消引用该指针。根据标准,这是否合法,或者上面的代码是否包含未定义的行为?

如果上面的程序合法,那么下面的程序也合法吗?

void bar(int&);
void baz();

void foo(std::vector<int>& v) {
    int& reference_to_last = v.back();
    if (v.size() > 0 && reference_to_last == 42) {
        bar(reference_to_last);
    } else {
        baz();
    }
}
Run Code Online (Sandbox Code Playgroud)

参考std::vector::back

回调空容器会导致未定义的行为。

所以我假设这个程序不合法。是否有 GCC 或 Clang 的编译器标志或任何静态分析器可以对上述代码发出警告?

c++ pointers reference pointer-arithmetic undefined-behavior

5
推荐指数
1
解决办法
118
查看次数