标签: pointers

C中的指针实现细节

我想知道违反我在下面列出的假设的架构.此外,我想知道所有架构的假设是否都是错误的(也就是说,如果它们中的任何一个完全错误的话).

  1. sizeof(int*)== sizeof(char*)== sizeof(void*)== sizeof(func_ptr*)

  2. 无论指向哪种数据类型,给定体系结构的所有指针的内存中表示都是相同的.

  3. 指针的内存中表示与与体系结构相同的位长的整数相同.

  4. 指针数据类型的乘法和除法仅被编译器禁止.注意:是的,我知道这是荒谬的.我的意思是 - 是否有硬件支持禁止这种不正确的用法?

  5. 所有指针值都可以转换为单个整数.换句话说,哪些架构仍然使用分段和偏移?

  6. 递增指针相当于添加sizeof(the pointed data type)指针存储的内存地址.如果pint32*p+1则等于4字节后的内存地址p.

我最习惯在连续的虚拟内存空间中使用指针.对于这种用法,我通常可以将它们视为数字线上的地址.请参阅堆栈溢出问题指针比较.

c pointers sizeof virtual-memory

16
推荐指数
4
解决办法
5104
查看次数

指针是否保证在C++中的`delete`后保留其值?

灵感来自这个问题.

假设在C++代码中我有一个有效的指针并且正确delete.根据C++标准,指针将变为无效(3.7.3.2/4 - 解除分配函数将使所有指针无效,指向解除分配的存储的所有部分).

至少在大多数实现中,它保留了值并将存储与以前完全相同的地址delete,但是使用该值是未定义的行为.

标准是否保证指针将保留其值或允许更改的值?

c++ pointers delete-operator

16
推荐指数
2
解决办法
3198
查看次数

对多维数组的一维访问:它是明确定义的行为吗?

我想我们都同意,通过以一维方式解引用(可能是偏移的)指向其第一个元素的指针来访问真正的多维数组被认为是惯用的C,例如:

void clearBottomRightElement(int *array, int M, int N)
{
    array[M*N-1] = 0;  // Pretend the array is one-dimensional
}


int mtx[5][3];
...
clearBottomRightElement(&mtx[0][0], 5, 3);
Run Code Online (Sandbox Code Playgroud)

然而,我的语言律师需要说服这实际上是明确定义的C!特别是:

  1. 是否标准保证编译器不会把填充例如,在中间mtx[0][2]mtx[1][0]

  2. 通常,索引关闭数组的末尾(除了结尾之外)是未定义的(C99,6.5.6/8).所以以下内容显然是未定义的:

    struct {
        int row[3];           // The object in question is an int[3]
        int other[10];
    } foo;
    int *p = &foo.row[7];     // ERROR: A crude attempt to get &foo.other[4];
    
    Run Code Online (Sandbox Code Playgroud)

    因此,根据相同的规则,人们会期望以下内容未定义:

    int mtx[5][3];
    int (*row)[3] = &mtx[0];  // The object in question is still an int[3]
    int *p = &(*row)[7]; …
    Run Code Online (Sandbox Code Playgroud)

c standards pointers multidimensional-array language-lawyer

16
推荐指数
2
解决办法
5774
查看次数

如何回答有关常量指针的面试测试?

我接受了一次采访,他们问了我这个问题

#include<stdio.h>
int main ()
{
int* const p=NULL;
int const *q=NULL;
p++;
q++;
printf("%d\n",p);
printf("%d\n",q);
}
Run Code Online (Sandbox Code Playgroud)

以上程序将如何表现

a)p将增加4个字节;
和q也将增加4个字节;

b)p将为零
q将指向前面4个字节的存储器;

c)错误将出现在上述程序中

我无法理解这些陈述之间的区别

int* const p=NULL;
int const *q=NULL;
Run Code Online (Sandbox Code Playgroud)

c pointers

16
推荐指数
2
解决办法
9128
查看次数

C free():指针无效

我正在自学C.我的目标是创建一个C函数,它只是遍历一个查询字符串并在&符号和等号上分开.我对Valgrind的这个错误感到困惑.

==5411== Invalid free() / delete / delete[] / realloc()
==5411==    at 0x402AC38: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5411==    by 0x804857C: main (leak.c:28)
==5411==  Address 0x420a02a is 2 bytes inside a block of size 8 free'd
==5411==    at 0x402AC38: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==5411==    by 0x804857C: main (leak.c:28)
==5411== 
==5411== 
==5411== HEAP SUMMARY:
==5411==     in use at exit: 0 bytes in 0 blocks
==5411==   total heap usage: 1 allocs, 2 frees, 8 bytes allocated
==5411== 
==5411== All heap blocks were freed -- no …
Run Code Online (Sandbox Code Playgroud)

c free valgrind pointers

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

2D阵列的行为

我创建了一个2D数组,并尝试打印某些值,如下所示:

int a[2][2] = { {1, 2}, 
                {3, 4}};

printf("%d %d\n", *(a+1)[0], ((int *)a+1)[0]);
Run Code Online (Sandbox Code Playgroud)

输出是:

3 2
Run Code Online (Sandbox Code Playgroud)

我理解为什么3是第一个输出(a+1指向第二行,我们打印它的0th元素.

我的问题是关于第二个输出,即2.我的猜测是,由于类型转换aint *,所述2D阵列像一维数组进行处理,并且因此a+1充当指向2nd元素,所以我们得到的输出作为2.

我的假设是正确的还是背后还有其他一些逻辑?
另外,原来什么是a被当作​​指针int (*)[2]int **?的类型?

c c++ arrays pointers output

16
推荐指数
2
解决办法
625
查看次数

在Swift中使用AudioBufferList

我在Swift中有一个桥接函数,其中一个参数在C中AudioBufferList *.在Swift中,这会生成一个UnsafePointer<AudioBufferList>.我设法通过调用来引用指针audioData[0](有更好的方法吗?).但我正在努力接下来的两个层次:他们和他们/ 成员的.mBuffers阵列. AudioBuffervoid *UnsafePointer<()> .mData

在C中它就是这样

Float32 *audioData = (Float 32*)abl->mBuffers[0]->mData;
output = audioData[sampleNum]...
Run Code Online (Sandbox Code Playgroud)

在Swift中,第一个奇怪的事情是它不会让我访问元素,mBuffers但是当我作为属性访问它时非常高兴.换句话说,这工作,甚至有正确的数据(对于mBuffers我认为的第一个成员)...

println(abl[0].mBuffers.mNumberChannels)  // But .mBuffers should be an []!
Run Code Online (Sandbox Code Playgroud)

其次,让我打印出.mData下标,但价值总是如此()

println(abl[0].mBuffers.mData[10])  // Prints '()'
Run Code Online (Sandbox Code Playgroud)

我已经尝试了各种铸造操作和访问多个索引但无济于事......任何想法?

以下是C和Swift定义AudioBufferList,AudioBuffer为方便起见......

// C
struct AudioBufferList
{
    UInt32      mNumberBuffers;
    AudioBuffer mBuffers[1]; // this is a variable length array of mNumberBuffers elements
    // ...and a bit more for c++
}


struct …
Run Code Online (Sandbox Code Playgroud)

pointers casting objective-c ios swift

16
推荐指数
2
解决办法
6933
查看次数

printf("%p")并转换为(void*)

在最近的一个问题中,有人提到当使用printf打印指针值时,调用者必须将指针强制转换为void*,如下所示:

int *my_ptr = ....

printf("My pointer is: %p", (void *)my_ptr);
Run Code Online (Sandbox Code Playgroud)

对于我的生活,我无法弄清楚为什么.我发现了这个问题,几乎是一样的.问题的答案是正确的 - 它解释了整数和指针的长度不一定相同.

这是当然的,真实的,但是当我已经在的情况下有一个指针,像上面,我为什么要由铸铁int *void *?什么时候int*与void*不同?事实上,什么时候(void *)my_ptr生成任何与简单不同的机器代码my_ptr

更新:多个知识渊博的响应者引用了标准,说传递错误的类型可能会导致未定义的行为.怎么样?我期望printf("%p", (int *)ptr)printf("%p", (void *)ptr)生成完全相同的堆栈帧.两个调用何时生成不同的堆栈帧?

c printf pointers

16
推荐指数
5
解决办法
2705
查看次数

Go指针 - 通过指针将值附加到切片

我有一个结构ProductData及其实例p,它有一个slice属性:

type ProductInfo struct {
    TopAttributes []map[string]interface{}
}
Run Code Online (Sandbox Code Playgroud)

我想设置TopAttributes如下

func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    setAttribute(p.TopAttributes, key, value)
}

func setAttribute(p []map[string]interface{}, key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    p = append(p, val)
}
Run Code Online (Sandbox Code Playgroud)

但这似乎不起作用.

但是,当我将方法定义为:时,还有另一种方法可以正常工作:

   func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    p.setAttribute(key, value)
}

func (p *ProductInfo) setAttribute(key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    p.TopAttributes = append(p.TopAttributes, val)
}
Run Code Online (Sandbox Code Playgroud)

我想找出它为什么不起作用.我的代码中没有错误,但数据是空的.我试图这样做使它成为一个泛型函数,因为我有另一个BottomAttributes必须以相同的方式设置.

pointers go slice

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

C++ const通过指针改变了,还是它?

在c中,可以使用像这样的指针来改变const:

//mainc.c
#include <stdio.h>

int main(int argc, char** argv) {
    const int i = 5;
    const int *cpi = &i;

    printf("  5:\n");
    printf("%d\n", &i);
    printf("%d\n", i);
    printf("%d\n", cpi);    
    printf("%d\n", *cpi);   

    *((int*)cpi) = 8;
    printf("  8?:\n");
    printf("%d\n", &i);
    printf("%d\n", i);
    printf("%d\n", cpi);
    printf("%d\n", *cpi);
}
Run Code Online (Sandbox Code Playgroud)

从输出中可以看出常量已更改: mainc输出

如果我们在c ++中尝试相同:

//main.cpp
#include <iostream>

using std::cout;
using std::endl;

int main(int argc, char** argv) {
    const int i = 5;
    const int *cpi = &i;

    cout << "  5:" << '\n';
    cout << &i << …
Run Code Online (Sandbox Code Playgroud)

c c++ pointers const

16
推荐指数
2
解决办法
1500
查看次数