我有这段代码.它似乎在这里取消引用空指针,但随后按位与结果和unsigned int.我真的不明白整个部分.它打算做什么?这是指针算术的一种形式吗?
struct hi
{
long a;
int b;
long c;
};
int main()
{
struct hi ob={3,4,5};
struct hi *ptr=&ob;
int num= (unsigned int) & (((struct hi *)0)->b);
printf("%d",num);
printf("%d",*(int *)((char *)ptr + (unsigned int) & (((struct hi *)0)->b)));
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是44.但它是如何工作的?
可能重复:
有没有理由在删除之前检查NULL指针?
我经常在代码中看到以下内容:
if(pointer)
delete pointer;
Run Code Online (Sandbox Code Playgroud)
根据我的理解,删除空指针是安全的,那么这个检查有什么意义呢?
我知道,NULL == (void *)0但提到它可以表示为一个不包含全零的值.困扰我的是,如果这些代码片段对所有代码都是等价的(any_type *):
any_type *val;
if (val) { ... };
Run Code Online (Sandbox Code Playgroud)
和
if (val != NULL) { ... };
Run Code Online (Sandbox Code Playgroud) 有时,C API可能需要NULL指针.
CGO有可能吗?
例如,我想strcmp()在Go语言程序中传递一个null参数:
package strutil
/*
#include <stdlib.h>
#include <string.h>
*/
import (
"C"
"unsafe"
)
func StrCmp(a, b string) int {
pca := C.CString(a)
defer C.free(pca)
pcb := C.CString(b)
defer C.free(pcb)
ret := C.strcmp(pca, pcb)
return int(ret)
}
Run Code Online (Sandbox Code Playgroud)
如果我设置pca为nil,则会发生此错误:
Exception 0xc0000005 0x0 0x0 0x76828b21
PC=0x76828b21
signal arrived during cgo execution
strutil._Cfunc_strcmp(0x0, 0x761b00, 0x0)
strutil/_obj/_cgo_gotypes.go:79 +0x49
strutil.StrCmp(0x19, 0x10, 0x4bbf38, 0xa, 0x1fbc1f98, 0x0, 0x0, 0xffff, 0x0, 0x0, ...)
Run Code Online (Sandbox Code Playgroud)
那么,我怎样才能将NULL传递给strcmp?
谢谢
这是C代码。
int main() {
int i = 10, *p = &i;
printf("%ld", p - (int *) NULL);
}
Run Code Online (Sandbox Code Playgroud)
对于指针算术部分,'gcc'和'clang'均在其汇编输出中生成'sar rax,2'指令。有人可以解释这种情况下的指针算术与算术右移有何关系。
当尝试利用C99函数原型语法为函数参数指定非null指针时,我在clang和gcc之间遇到了一些不一致的行为:
可以声明并定义一个函数,以接收指向最小大小的数组的非null指针。例如:
char *mystrcpy(char dest[restrict static 1], char const src[restrict static 1]);
声明函数mystrcpy接受非空的char数组指针。
此定义比strcpy使用更经典形式的标准定义更严格:
char *strcpy(char restrict *dest, const char restrict *src);
如果没有为C编译器提供任何有关约束的信息,则参数为非null。
我编写了一个测试程序来验证这两个原型的兼容性,并且惊讶地发现它们确实兼容,尽管第一个中包含的信息比第二个中包含的信息更多。这些事实进一步令人惊讶:
strcpy接收空参数。strcpy接收了空参数,而不是不接收mystrcpy。strcpy或mystrcpy给使用两种语法定义的函数指针都不会引起任何警告。我的问题是:这些观察结果是否与C标准一致,或者gcc和/或clang在函数参数
static内对C99 关键字的实现不正确[]?
这是代码:
#include <stdio.h>
#include <string.h>
static char *mystrcpy(char dest[restrict static 1], char const src[restrict static 1]) {
char *p = dest;
while ((*p++ = *src++) != '\0')
continue;
return …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 来学习 Fortran2018 gfortran。在使用指针时,我注意到似乎没有测试空指针的工具。所以我有两个问题:
更实际地说,在下面的代码片段中:我们如何在执行过程中的任何时刻找出分配给p是否“安全”?allocate(可能会想象一个更复杂的、nullify和语句序列deallocate。)
program test
implicit none
real, pointer :: p
! p = 333.333 ! Segfault, p is neither defined, nor allocated
! Since p is not defined, checking whether it's
! associated to a target gives arbitrary results:
print *, "Start: Pointer p associated? ", associated(p) ! Result: True or False
nullify(p) ! Now p is defined, but `null`
print *, "Nullyfied: …Run Code Online (Sandbox Code Playgroud) C++11引入了nullptr我没有的关键字。
我想有NULL来自 C的宏,我从这里和这里的一些东西中读到了在 C++ 中使用的宏,但我仍然不确定在这个旧的 C++ 标准中检查空指针的正确方法是什么。
我基本上希望能够使用 Boost Test 为我的测试用例编写此代码:
aWrapperDataStructure x;
BOOST_CHECK_NE(x.get_ptr(), static_cast<decltype(x.get_ptr())>(nullptr));
Run Code Online (Sandbox Code Playgroud)
但也许,正如 Tutorials Point 建议的那样,考虑到限制,这样的事情更合适:
BOOST_CHECK(x.get_ptr()); //true when not NULL
Run Code Online (Sandbox Code Playgroud)
不过,关于这方面的一些事情让我感到厌烦,所以我想知道这里的最佳做法是什么。如果它在网上的某个地方,或者在 SO 上,它已经被埋藏很久了,我找不到它。谢谢!
由于指针算术是在同一数组中定义的,我怀疑是否可以NULL从另一个数组中减去NULL。我担心的是:
//first and second can both either be from the same array
//or be both NULL
prtdiff_t sub(void *first, void *second){
//Do I really need this condition?
if(!first && !second)
return (ptrdiff_t) 0;
return second - first;
}
Run Code Online (Sandbox Code Playgroud) 总结 C 标准,特别是ISO/IEC 9899:201x \xc2\xa76.3.2.3 - 3:
\n如果将指针与常量文字进行比较0,则检查该指针是否为空指针。这0被称为空指针常量。C 标准定义0转换为类型void *既是空指针又是空指针常量。
现在,如果我们看一下(void *)0它是一个指向 的地址(在这种情况下是非法的)void。
通常我们可以将这样的地址转换为任何适当的指针数据类型并取消引用它,但在这里即使在将其转换为其他指针类型之后,取消引用它也是非法的。
\n所以我的疑问是:
\n我们可以(void *)0按照其定义的方式调用 void 指针吗?
另请参阅下面的代码:
\nvoid *pointer = NULL;\nRun Code Online (Sandbox Code Playgroud)\n现在我该怎么称呼它呢?void 指针、空指针还是 null void 指针?
\n