如果我有这个代码,例如:
int num = 5;
int *ptr = #
Run Code Online (Sandbox Code Playgroud)
以下两个功能有什么区别?
void func(int **foo);
void func(int *foo);
Run Code Online (Sandbox Code Playgroud)
我在哪里调用函数:
func(&ptr);
Run Code Online (Sandbox Code Playgroud)
我意识到前两者采用指针作为参数指针,而第二种只采用指针.
如果我传入func(&ptr)
,我实际上是在传入一个指针.指针指向另一个指针有什么区别?
我相信后者会给出一个不兼容的警告,但只要你知道你在做什么,似乎细节无关紧要.似乎可能为了可读性和理解,前者是更好的选择(2星指针),但从逻辑的角度来看,有什么区别?
代码很简单,本教程基本上是直接的.我正在运行Arch Linux并且存储了OpenCV库/usr/include/
.我也检查过以确保它/usr/include
在我的PATH中.
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
using namespace cv;
int main(int argc, char** argv){
Mat image;
Mat grayImage;
if(!argv[1]){
std::cerr << "No image data!" << std::endl;
return -1;
}
image = imread(argv[1], 1);
cvtColor(image, grayImage, CV_BGR2GRAY);
imwrite("Gray_Image.jpg", grayImage);
namedWindow(argv[1], CV_WINDOW_AUTOSIZE);
namedWindow("Gray Image", CV_WINDOW_AUTOSIZE);
imshow(argv[1], image);
imshow("Gray Image", grayImage);
waitKey(0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器进程成功查找并包含这些头文件,但我仍然在编译时得到未定义的引用错误.如果你查看我包含的头文件,他们还包括其他文件/usr/include/opencv2
.我检查过,这样的头文件确实存在.
有任何想法吗?
/tmp/ccudBcqD.o: In function `main':
test.cpp:(.text+0xc0): undefined reference to `cv::imread(std::string const&, int)'
test.cpp:(.text+0x11f): undefined reference to `cv::_OutputArray::_OutputArray(cv::Mat&)' …
Run Code Online (Sandbox Code Playgroud) 在eclipse中,您可以点击"输入",IDE将自动将您带到行尾,并放置一个分号.
在IntelliJ中,如果你点击shift-enter,你会得到类似的行为,而不是添加分号.我已经阅读并尝试过cntrl-shift-enter,你会得到完全相同的行为.然而,这是一个非常难以使用的关键组合,至少比使用Eclipse的一键式方法要多得多.
有任何想法吗?
我无法弄清楚这一点.也许是因为凌晨2点.无论如何,我在这里不知所措.
#include <stdio.h>
int main()
{
char array[] = "123456789";
char* ptr = array;
printf("%c\n", *(ptr++));
printf("%c\n", *ptr);
*ptr = array[3];
printf("%c\n", *(ptr++));
printf("%c\n\n", *ptr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果是:
1
2
4
3
Run Code Online (Sandbox Code Playgroud)
我有一个指针,我指定array
.
然后我打印,我认为将是第一个索引('2'
),而是得到1
.- 所以,我假设它*(ptr++)
实际上是取消引用,然后才增加指针.
然后我重新分配ptr
第四个索引('4'
)并重复步骤2.这样就可以正常工作,因为我看到C在解除引用之前不会先计算括号.
然后我打印新增加ptr
的显示('5'
)...我得到了3
?
那是怎么回事,第1步和第2步以及第3步和第4步是相同的,但是我得到了不同的结果?
本网站上有很多关于在使用后释放指针的问题,并且进一步将它们设置为NULL.争论很激烈,主题看似平分.例如:这个问题.一般来说,我对释放指针很困惑.
想象一下,你有一个指向一些内存空间的指针.使用空格后,释放指针但不要将其设置为NULL.稍后,你有另一个指针调用malloc()
,或者一些模拟,并且它被分配了内存,包括先前释放的内存(原始指针仍然指向).如果这个新指针写入此内存块,会发生什么?直觉上什么都不会发生,但前面提供的链接中的OP写道它会使程序崩溃.
所以我的问题是:
给定一个释放指针,是什么阻止您将指针重新分配给新的内存位置?为什么重用已释放的指针是"坏"的做法?如果调用free(ptr)
只将此内存返回给操作系统,为什么不能将指针重新分配给其他内存位置并重新使用?
char *ptr = malloc(sizeof(*ptr)); //first allocation
free(ptr); //release memory
ptr = NULL;
ptr = malloc(sizeof(*ptr)); //reallocate
Run Code Online (Sandbox Code Playgroud)为什么要写入以前释放的内存块,仍然有原始指针,导致程序崩溃? - 请参阅上面链接的问题的第一篇文章的第一段(如果我误解了本段的意图,请解释,因为不明确是否再次使用该指针来写入内存或创建新指针.)
对于速记IF-ELSE语句,C具有以下语法
(integer == 5) ? (TRUE) : (FALSE);
Run Code Online (Sandbox Code Playgroud)
我经常发现自己只需要声明的一部分(TRUE或FALSE)并使用它
(integer == 5) ? (TRUE) : (0);
Run Code Online (Sandbox Code Playgroud)
我只是想知道是否有办法不使用这种速记符号包含声明的ELSE部分?
我需要在运行时动态链接库并使用解析一系列函数dlsym
.我的第一个想法是使用一个函数指针数组,通过利用char *
表示符号名称的辅助数组,可以很容易地迭代.
但是,问题在于并非所有函数都使用相同的参数.有没有办法在数组中使用泛型函数指针,但是将它分配给限制性更强的函数指针原型?例如:
如果我需要解决这些功能:
int (*functionA)(int)
char (*functionB)(char,int)
Run Code Online (Sandbox Code Playgroud)
是否有可能做某些事情(伪似......)
void* functionList(...)[2] = {functionA, functionB};
Run Code Online (Sandbox Code Playgroud)
随着
char FuncNameA[] = "functionA";
char FuncNameB[] = "functionB";
char *functionNames[2] = {FuncNameA, FuncNameB};
Run Code Online (Sandbox Code Playgroud)
用于循环调用dlsym
符号解析的目的
int i = 0;
for(; i<2; i++)
functionList[i] = dlsym(DL_OPEN_HANDLE, functionNames[i]);
Run Code Online (Sandbox Code Playgroud)
其中DL_OPEN_HANDLE将由之前的调用定义dlopen
.
我正在运行一个内存访问实验,其中使用了一个2D矩阵,每行都是一个内存页面的大小.该实验包括使用行/列主要读取每个元素,然后使用行/列主要写入每个元素.正在访问的矩阵是使用全局范围声明的,以简化编程要求.
这个问题的关键是,在静态声明测试矩阵的情况下,编译器将值初始化为零,我发现的结果非常有趣.当我第一次读取操作时,即
rowMajor_read();
colMajor_read();
rowMajor_write();
colMajor_write();
Run Code Online (Sandbox Code Playgroud)
然后我的colMajor_read操作很快就完成了.
但是,如果我在阅读之前进行写操作,我们有:
rowMajor_write();
colMajor_write();
rowMajor_read();
colMajor_read();
Run Code Online (Sandbox Code Playgroud)
并且列主要读取操作增加了近一个数量级.
我认为它必须与编译器如何优化代码有关.由于每个元素的全局矩阵都相同,编译器是否完全删除了读取操作?或者以某种方式"更容易"从内存中读取相同为零的值?
我没有传递任何关于优化的特殊编译器命令,但我确实以这种方式声明了我的函数.
inline void colMajor_read(){
register int row, col;
register volatile char temp __attribute__((unused));
for(col = 0; col < COL_COUNT; col++)
for(row = 0; row < ROW_COUNT; row++)
temp = testArray[row][col];
}
Run Code Online (Sandbox Code Playgroud)
因为我遇到了编译器temp
从上面的函数中完全删除变量的问题,因为它从未被使用过.我认为,同时具有volatile
和__attribute__((unused))
是多余的,但我把它不过.我的印象是没有对volatile变量实现优化.
有任何想法吗?
我查看了生成的程序集,结果与colMajor_read函数的结果相同.(汇编)非内联版本:http://pastebin.com/C8062fYB
假设我在一个程序中遇到一个实例,我要么释放一个NULL指针,要么首先检查它是否为NULL并跳过free()
函数调用.
简单地释放NULL指针会更有效吗?我搜索了一下,显然,对于C89之后的实现,释放NULL指针是无害的 - 所以决定归结为效率.
我的假设是,在打电话时可能会产生相当多的开销free()
.因此,在调用free()
函数之前,可能需要进行简单的逻辑检查.
tl;博士版,
在进行调用时,内部发生了什么free()
,可能会在释放之前首先检查或指针是否为NULL,从而或多或少有效?
如果我说:
import java.awt.event.ActionListener;
Run Code Online (Sandbox Code Playgroud)
我得到了ActionListener类.如果我说:
import java.awt.event.*;
Run Code Online (Sandbox Code Playgroud)
我得到包含 ActionListener 的事件类?或者更好的是:
import java.awt.*;
Run Code Online (Sandbox Code Playgroud)
我认为,如果你包括一个类,就像在前两个例子中那样,你有效地导入了该类并继承了它的所有子类.但是,当我仅使用最后一行时,例如,Eclipse经常显示错误,说它无法解析某些项目,并建议我同时包含java.awt和java.awt.event.