我见过一个函数,其原型是:
int myfunc(void** ppt)
Run Code Online (Sandbox Code Playgroud)
该函数在C文件中作为a = myfunc(mystruct**var1)调用;
其中mystruct是我们拥有的结构之一的typedef.
这在MSVC6.0中没有任何编译错误,但是当我用其他一些C编译器编译它时,它会在调用此函数的地方出错,并显示错误消息:
类型mystruct**的参数与void**类型的参数不兼容
myfunc()的参数保持为void**,因为它似乎是一个通用的malloc类函数,可以使用各种结构变量类型进行内存分配
mystruct**,但它没有工作]-广告
我正在查看来自不安全编程的示例abo3.c,并且我没有在下面的示例中讨论转换.有人可以开导我吗?
int main(int argv,char **argc)
{
extern system,puts;
void (*fn)(char*)=(void(*)(char*))&system;
char buf[256];
fn=(void(*)(char*))&puts;
strcpy(buf,argc[1]);
fn(argc[2]);
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
那么 - 系统的投射和投注是什么?他们都回归了int,为什么要把它变成无效?
我非常感谢对整个计划的解释.
[编辑]
感谢您的投入!
Jonathan Leffler,实际上代码有"坏"的原因.它应该是可利用的,溢出缓冲区和函数指针等.mishou.org有一篇关于如何利用上述代码的博客文章.其中很多仍然在我头上.
bta,我从上面的博客文章中得知,转换系统会以某种方式阻止链接器删除它.
有一点不能立即明确的是系统和放置地址都写在同一个位置,我想这可能是gera所说的"所以链接器不会删除它".
虽然我们讨论的是函数指针的主题,但现在我想问一个后续问题,即语法更清晰.我正在使用函数指针查看一些更高级的示例,并偶然发现这个可憎的东西,取自托管shellcode的站点.
#include <stdio.h>
char shellcode[] = "some shellcode";
int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
}
所以数组被强制转换为函数返回void,引用和调用?这看起来很讨厌 - 所以上面代码的目的是什么?
[/编辑]
我正在尝试声明一个占用零字节的C++变量.它在一个联合中,我以int [0]的类型开始.我不知道这是否实际上是零字节(虽然sizeof(int [0])是0).我需要一种更好的方法来声明一个0字节类型,并希望可以将其类型化为nullType或emptyType.变量在一个联合中,所以无论如何最终都会保留内存.我尝试了无效的机会,但是C++抱怨道.我正在使用Ubuntu 10.10,包含当前版本的内核,以及最新的GCC.这是联盟:
union RandomArgumentTypesFirst
{
uint uintVal;
nullType nullVal;
}
Run Code Online (Sandbox Code Playgroud)
这是typedef:
typedef int[0] nullType;
Run Code Online (Sandbox Code Playgroud)
编译器对typedef说了这个:
error: variable or field ‘nullVal’ declared voidmake[2]:
Run Code Online (Sandbox Code Playgroud)
当我输入时int[0],它有效.有什么建议?
编辑:正如@fefe在评论中所说,int[0]可能由编译器作为扩展提供.GCC的网站说默认情况下编译器有很多扩展.
我有一个这种类:
class A<TResult>
{
public TResult foo();
}
Run Code Online (Sandbox Code Playgroud)
但有时我需要将此类用作非泛型类,即类型TResult为void.
我无法通过以下方式实例化该类:
var a = new A<void>();
Run Code Online (Sandbox Code Playgroud)
另外,我宁愿不指定省略尖括号的类型:
var a = new A();
Run Code Online (Sandbox Code Playgroud)
我不想重写全班,因为它做同样的事情.
我想创建一个SwingWorker具有最终和中间结果类型的具体类void.我写了以下代码:
class AnswerWorker extends SwingWorker<void, void> {
protected void doInBackGround() {
System.out.println("what is your problem!!");
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
Multiple markers at this line-
Syntax error on token "void", Dimensions expected after this token.
Syntax error on token "void", Dimensions expected after this token.
Run Code Online (Sandbox Code Playgroud)
然而,当我将代码更改void为Void(即小v到大写V)时,它工作正常,尽管我仍然被迫return null;在doInBackground()方法结束时.
为什么是这样?我知道Void是一个java.lang包中的类,但是文档没有说太多关于它的内容(至少我不能遵循它:p)
Thanx提前!!
假设我有一些代码:
public int doSomething(int x)
{
otherMethod(x);
System.out.println("otherMethod is complete.");
return 0;
}
public void otherMethod(int y)
{
//method body
}
Run Code Online (Sandbox Code Playgroud)
由于otherMethod的返回类型为void,该doSomething方法如何知道何时otherMethod完成,因此它可以转到下一个类似并打印" otherMethod已完成".
编辑:添加return 0;到doSomething方法,所以示例代码将编译.
private void SaveMoney(string id...)
{
...
}
public void DoSthWithMoney(string action,string id...)
{
if(action=="save") return SaveMoney(string id);
...
}
Run Code Online (Sandbox Code Playgroud)
为什么C#不允许我通过公共函数返回私有函数的空白?它甚至是相同的数据类型"无效"......
或者数据类型是否无效?
以下代码真的是最短的解决方法吗?
if(action=="save") {
SaveMoney(string id);
return;
}
Run Code Online (Sandbox Code Playgroud) 目前我们正在学习如何编程AVR微控制器(仅限Ansi C89标准).部分包含的驱动程序是一个标题,用于处理调度,即以不同的速率运行任务.我的问题是与文档中的引用有关:
"每个任务必须通过使用静态局部 变量来维护自己的状态."
那是什么意思呢?他们似乎传递void*给维持状态的功能但是不使用它?
看一下我收集的文件中的代码,这就是他们的意思:
{.func = led_flash_task, .period = TASK_RATE / LED_TASK_RATE, .data = 0}
/* Last term the pointer term */
Run Code Online (Sandbox Code Playgroud)
有一个函数在数组中使用上述参数运行,但它只作为调度程序.然后功能led_flash_task是
static void led_flash_task (__unused__ void *data)
{
static uint8_t state = 0;
led_set (LED1, state); /*Not reall important what this task is */
state = !state; /*Turn the LED on or off */
}
Run Code Online (Sandbox Code Playgroud)
并从标题
#define __unused__ __attribute__ ((unused))
Run Code Online (Sandbox Code Playgroud)
而传递void *data是为了维持任务的状态?这是什么意思?
谢谢您的帮助
我想知道为什么以下代码:
void foo(void);
void foo()
{
}
Run Code Online (Sandbox Code Playgroud)
在gcc中有效.在C中,没有重载和上面的声明(事实上,其中一个是定义)声明两个不同的函数(第一个不接受任何参数,第二个可以接受任何数量的参数)类型).
但是,如果我们为第一个函数提供定义:
void foo(void)
{
}
void foo()
{
}
Run Code Online (Sandbox Code Playgroud)
由于重新定义,此次编译失败.但是,第一个代码仍然是正确的,可能会令人困惑,如下所示:
void foo(void);
int main(void)
{
foo(); //OK
//foo(5); //Wrong, despite ->the definition<- allows it
}
void foo()
{
}
Run Code Online (Sandbox Code Playgroud)
另一方面,这样的事情是无效的:
void foo(int);
void foo() //error: number of arguments doesn't match prototype
{
}
Run Code Online (Sandbox Code Playgroud)
我认为与我的第一个前面的代码相比,编译器的行为有点奇怪.int是不等于(/*empty list*/),也不是void.
有谁能解释一下?
我使用void指针在C中实现了一个基本的队列结构.程序如下:
memcpy()它有一个本地副本.结构本身看起来像这样:
struct queue
{
void* start; //pointer to the beginning of queue
void* end; //-||- to the end
size_t memsize; //size of allocated memory, in bytes
size_t varsize; //size of a single variable, in bytes
void* initial_pointer; //position of the start pointer before pop() operations
};
Run Code Online (Sandbox Code Playgroud)
start和end只是指向当前分配的内存块中某个位置的void指针.如果我在队列上推送元素,我将结束指针递增varsize.如果我pop(),我只是递减结束指针varsize.
我不认为我应该在这里发布功能代码,它超过100行.
问题:这被认为是好的还是坏的做法?为什么不)?
注意:我知道C中的队列还有很多其他选项.我只是询问这个的质量.
编辑:可以在这里获得实现:http:// 89.70.149.19 /stuff/queue.txt(删除空格)