我想知道违反我在下面列出的假设的架构.此外,我想知道所有架构的假设是否都是错误的(也就是说,如果它们中的任何一个完全错误的话).
sizeof(int*)== sizeof(char*)== sizeof(void*)== sizeof(func_ptr*)
无论指向哪种数据类型,给定体系结构的所有指针的内存中表示都是相同的.
指针的内存中表示与与体系结构相同的位长的整数相同.
指针数据类型的乘法和除法仅被编译器禁止.注意:是的,我知道这是荒谬的.我的意思是 - 是否有硬件支持禁止这种不正确的用法?
所有指针值都可以转换为单个整数.换句话说,哪些架构仍然使用分段和偏移?
递增指针相当于添加sizeof(the pointed data type)指针存储的内存地址.如果p是int32*则p+1则等于4字节后的内存地址p.
我最习惯在连续的虚拟内存空间中使用指针.对于这种用法,我通常可以将它们视为数字线上的地址.请参阅堆栈溢出问题指针比较.
灵感来自这个问题.
假设在C++代码中我有一个有效的指针并且正确delete.根据C++标准,指针将变为无效(3.7.3.2/4 - 解除分配函数将使所有指针无效,指向解除分配的存储的所有部分).
至少在大多数实现中,它保留了值并将存储与以前完全相同的地址delete,但是使用该值是未定义的行为.
标准是否保证指针将保留其值或允许更改的值?
我想我们都同意,通过以一维方式解引用(可能是偏移的)指向其第一个元素的指针来访问真正的多维数组被认为是惯用的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!特别是:
是否标准保证编译器不会把填充例如,在中间mtx[0][2]和mtx[1][0]?
通常,索引关闭数组的末尾(除了结尾之外)是未定义的(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)我接受了一次采访,他们问了我这个问题
#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.我的目标是创建一个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) 我创建了一个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.我的猜测是,由于类型转换a为int *,所述2D阵列像一维数组进行处理,并且因此a+1充当指向2nd元素,所以我们得到的输出作为2.
我的假设是正确的还是背后还有其他一些逻辑?
另外,原来什么是a被当作指针int (*)[2]或int **?的类型?
我在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) 在最近的一个问题中,有人提到当使用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)生成完全相同的堆栈帧.两个调用何时生成不同的堆栈帧?
我有一个结构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必须以相同的方式设置.
在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)
如果我们在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)