我遇到了以下C拼图:
问:为什么以下程序会在IA-64上发生段错误,但在IA-32上运行良好?
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道int64位机器的大小int可能与指针的大小不同(可能是32位,指针可能是64位).但我不确定这与上述计划有什么关系.有任何想法吗?
这个问题在那里向C大师们提出:
在C中,可以如下声明指针:
char (* p)[10];
Run Code Online (Sandbox Code Playgroud)
..这基本上表明这个指针指向一个10个字符的数组.声明这样的指针的巧妙之处在于,如果尝试将不同大小的数组指针分配给p,则会出现编译时错误.如果您尝试将简单char指针的值赋给p,它也会给出编译时错误.我用gcc尝试了这个,它似乎适用于ANSI,C89和C99.
在我看来,声明像这样的指针非常有用 - 特别是在将指针传递给函数时.通常,人们会编写这样一个函数的原型:
void foo(char * p, int plen);
Run Code Online (Sandbox Code Playgroud)
如果您期望具有特定大小的缓冲区,则只需测试plen的值.但是,您无法保证将p传递给您的人真的会在该缓冲区中为您提供有效的内存位置.你必须相信调用这个函数的人正在做正确的事情.另一方面:
void foo(char (*p)[10]);
Run Code Online (Sandbox Code Playgroud)
..会强制调用者为您提供指定大小的缓冲区.
这似乎非常有用,但我从未见过在我遇到过的任何代码中都声明了这样的指针.
我的问题是:人们有没有理由不宣布像这样的指针?我没有看到一些明显的陷阱吗?
从理论上讲,我可以这么说
free(ptr);
free(ptr);
Run Code Online (Sandbox Code Playgroud)
是一个内存损坏,因为我们释放已经释放的内存.
但是如果
free(ptr);
ptr=NULL;
free(ptr);
Run Code Online (Sandbox Code Playgroud)
由于操作系统将以不确定的方式运行,我无法对此进行实际的理论分析.无论我在做什么,这种记忆是否会腐败?
释放空指针有效吗?
我知道Java没有指针,但我听说Java程序可以用指针创建,这可以由少数java专家完成.这是真的吗?
我今天去了一个面试,并得到了这个有趣的问题.
除了内存泄漏和事实上没有虚拟dtor,为什么这个代码会崩溃?
#include <iostream>
//besides the obvious mem leak, why does this code crash?
class Shape
{
public:
virtual void draw() const = 0;
};
class Circle : public Shape
{
public:
virtual void draw() const { }
int radius;
};
class Rectangle : public Shape
{
public:
virtual void draw() const { }
int height;
int width;
};
int main()
{
Shape * shapes = new Rectangle[10];
for (int i = 0; i < 10; ++i)
shapes[i].draw();
}
Run Code Online (Sandbox Code Playgroud) 当我无法移动/复制memmove()/ memcpy()作为边缘情况时,我是否需要处理案例
int numberOfBytes = ...
if( numberOfBytes != 0 ) {
memmove( dest, source, numberOfBytes );
}
Run Code Online (Sandbox Code Playgroud)
或者我应该在没有检查的情况下调用该函数
int numberOfBytes = ...
memmove( dest, source, numberOfBytes );
Run Code Online (Sandbox Code Playgroud)
是否需要检查前片段?
如何创建一个可以存储函数的Dictionary?
谢谢.
我有大约30多个可以从用户执行的功能.我希望能够以这种方式执行该功能:
private void functionName(arg1, arg2, arg3)
{
// code
}
dictionaryName.add("doSomething", functionName);
private void interceptCommand(string command)
{
foreach ( var cmd in dictionaryName )
{
if ( cmd.Key.Equals(command) )
{
cmd.Value.Invoke();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,函数签名并不总是相同,因此具有不同数量的参数.
在哪种情况下你想在c ++中使用这种性质的代码?
void foo(type *&in) {...}
void fii() {
type *choochoo;
...
foo(choochoo);
}
Run Code Online (Sandbox Code Playgroud) 我很不清楚在哪种情况下我会想要使用值接收器而不是总是使用指针接收器.
要从文档中回顾一下:
type T struct {
a int
}
func (tv T) Mv(a int) int { return 0 } // value receiver
func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver
Run Code Online (Sandbox Code Playgroud)
该文档还表示"对于类型,如基本类型,切片和小结构,值接收机是非常便宜,所以,除非所述方法的语义需要一个指针,一个值是接收机有效和明确的."
首先它说它"非常便宜",但更问题的是它比指针接收器便宜.所以我做了一个小的基准测试(gist上的代码)向我展示了,即使对于只有一个字符串字段的结构,指针接收器也更快.这些是结果:
// Struct one empty string property
BenchmarkChangePointerReceiver 2000000000 0.36 ns/op
BenchmarkChangeItValueReceiver 500000000 3.62 ns/op
// Struct one zero int property
BenchmarkChangePointerReceiver 2000000000 0.36 ns/op
BenchmarkChangeItValueReceiver 2000000000 0.36 ns/op
Run Code Online (Sandbox Code Playgroud)
(编辑:请注意第二点在较新的版本中无效,请参阅注释).
第二点它说,它是"高效和清晰",这更多的是品味问题,不是吗?就个人而言,我喜欢以任何方式使用相同的方式.效率在什么意义上?性能方面看来,指针几乎总是更有效率.使用一个int属性的少量测试运行显示Value接收器的最小优势(范围为0.01-0.1 ns/op)
有人能告诉我一个值接收器明显比指针接收器更有意义的情况吗?或者我在基准测试中做错了什么,我是否忽略了其他因素?