我试图使用HTTP从IP摄像头获取图像.相机需要HTTP基本身份验证,因此我必须添加相应的请求标头:
URL url = new URL("http://myipcam/snapshot.jpg");
URLConnection uc = url.openConnection();
uc.setRequestProperty("Authorization",
"Basic " + new String(Base64.encode("user:pass".getBytes())));
// outputs "null"
System.out.println(uc.getRequestProperty("Authorization"));
Run Code Online (Sandbox Code Playgroud)
我稍后将url对象传递给ImageIO.read(),并且,正如您所猜测的,我正在获取HTTP 401 Unauthorized,尽管user并且pass是正确的.
我究竟做错了什么?
我也试过了new URL("http://user:pass@myipcam/snapshot.jpg"),但这也行不通.
我正在通过静态编译最小程序并检查发出的系统调用来进行实验:
$ cat hello.c
#include <stdio.h>
int main (void) {
write(1, "Hello world!", 12);
return 0;
}
$ gcc hello.c -static
$ objdump -f a.out
a.out: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000004003c0
$ strace ./a.out
execve("./a.out", ["./a.out"], [/* 39 vars */]) = 0
uname({sys="Linux", node="ubuntu", ...}) = 0
brk(0) = 0xa20000
brk(0xa211a0) = 0xa211a0
arch_prctl(ARCH_SET_FS, 0xa20880) = 0
brk(0xa421a0) = 0xa421a0
brk(0xa43000) = 0xa43000
write(1, "Hello world!", 12Hello world!) = 12
exit_group(0) = …Run Code Online (Sandbox Code Playgroud) 我已经读过如果你声明这样的两个结构:
struct Node {
int a, b, c;
};
struct DerivedNode {
struct Node base;
int d, e, f;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用指针:
struct DerivedNode myDerivedNode;
struct Node *regularNode = (struct Node *) &myDerivedNode;
regularNode->a = 3;
Run Code Online (Sandbox Code Playgroud)
换句话说,地址偏移量a, b, c在struct Node和中是相同的struct DerivedNode.所以你可以从中获得一种多态性,在那里你可以传递一个强制(struct Node *)广播的DerivedNode指针,无论在哪里通常都会采用Node指针.
我的问题是这种行为是否得到保证.我知道有一些奇怪的内存对齐问题,编译器有时会重新排序字段以实现更好的内存打包.base除了开始之外,这个领域是否会位于任何地方struct DerivedNode?
C99标准规定:
当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素
请考虑以下代码:
struct test {
int x[5];
char something;
short y[5];
};
...
struct test s = { ... };
char *p = (char *) s.x;
char *q = (char *) s.y;
printf("%td\n", q - p);
Run Code Online (Sandbox Code Playgroud)
这显然打破了上述规则,因为p和q指针指向不同的"数组对象",并且根据规则,q - p差异是未定义的.
但在实践中,为什么这样的事情会导致未定义的行为?毕竟,struct成员按顺序排列(就像数组元素一样),成员之间有任何潜在的填充.确实,填充量会因实现而异,这会影响计算结果,但为什么结果应该是"未定义"?
我的问题是,我们可以假设标准只是对这个问题"无知",还是有充分的理由不扩大这个规则?难道不能将上述规则改为" 两者都应指向同一数组对象的元素或同一结构的成员 "吗?
我唯一怀疑的是分段内存架构,其中成员可能最终分成不同的段.是这样的吗?
我也怀疑这就是为什么GCC定义它自己的原因__builtin_offsetof,以便有一个"符合标准"的offsetof宏定义.
编辑:
正如已经指出的那样,标准不允许对void指针进行算术运算.它是一个GNU扩展,仅在GCC通过时才会触发警告-std=c99 -pedantic.我用void *指针替换char *指针.
我遇到了一些我完全不明白的事情.有一个函数原型:
typedef void ( * TMain ) ( void );
Run Code Online (Sandbox Code Playgroud)
和一个函数变量:
TMain myFunc = MyFunc;
...
myFunc ();
Run Code Online (Sandbox Code Playgroud)
当然,这很好用.为什么不呢.
从MAP文件我知道"MyFunc"位于0x20100位置.而现在有趣的事情.在赋值"myFunc = MyFunc;"之后 变量"myFunc" 不包含值0x20100而是0x20101!
我的问题是,我需要调用一个函数,我从表中知道地址.所以我想我可以这样做
myFunc = ( TMain ) myTable [ 5 ]; // that would be 0x20100
myFunc (); // which produces a proper crash
Run Code Online (Sandbox Code Playgroud)
但是,如果我这样做
myFunc = ( TMain ) ( ( Int8 * ) myTable [ 5 ] + 1 );
myFunc ();
Run Code Online (Sandbox Code Playgroud)
然后它工作.
这里发生了什么?我是否总是要添加1的偏移量,或者这或多或少是偶然的?或者有更好的(和工作)方式来完成任务?
非常感谢任何提示.沃尔特
我在C中实现了自己的哈希表函数,但目前它不支持调整大小.我想知道除了创建新的空哈希表并将所有内容移动到那里的蛮力方式之外还存在哪些算法?
我正在定义一个宏,它计算为一个常量字符串,保存文件名和行号,用于记录目的.
它工作正常,但我无法弄清楚为什么需要2个额外的宏 - STRINGIFY而且TOSTRING,当直觉暗示时__FILE__ ":" #__LINE__.
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define THIS_ORIGIN (__FILE__ ":" TOSTRING(__LINE__))
int main (void) {
/* correctly prints "test.c:9" */
printf("%s", THIS_ORIGIN);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎是一个丑陋的黑客.
具体是什么,这样逐步发生阶段有人能解释__LINE__正确字符串化,为什么既不__FILE__ ":" STRINGIFY(__LINE__)和__FILE__ ":" #__LINE__作品?
我对指令大小和可寻址空间感到困惑(我假设指令大小应该与地址位的大小相同.我在书中没有找到足够的解释)如果我是正确的,那么理论上如果我们有2 ^ 32 32位架构(RISC样式)内存的可寻址单元(字节)4字节大小的加载指令如何保存操作码以及地址?
cpu assembly operating-system instruction-set computer-architecture
我正在学习C语言,到目前为止对语言有了很好的理解,我最近实现了一个非常简单的单链表.我曾与Linus Torvalds一起观看过Ted演讲,他提到了良好的代码与糟糕的代码,并提供了从链接列表中删除条目的两个示例:
/*bad code*/
remove_list_entry(entry){
prev = NULL;
walk = head;
while(walk != entry){
prev = walk;
walk = walk->next;
}
if(!prev)
head = entry->next;
else
prev->next = entry->next;
/*good code*/
remove_list_entry(entry){
indirect = &head;
while ((*indirect) != entry)
indirect = &(*indirect)->next;
*indirect = entry->next;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,他的良好代码示例是有效的,但我自己也不会想到这一点.在使用C编程时,我可以遵循哪些良好实践建议?或者像他在他的例子中那样操纵指针的某些方法?除了在CI编程时要避免的坏习惯和做法,希望这不是一个太宽泛的问题.
我注意到,当printf/sprintf函数的格式字符串中的转换说明符与相应参数的类型或计数不匹配时,大量C编译器会发出警告.
在我看来,这似乎是一个概念上的突破,因为根据语言规范,C没有内置函数.
所有编译器都应该知道printf/sprintf是他们的原型而不是他们的语义.我知道printf/sprintf是标准的C函数,但是它们存在于一个单独的库libc中,你必须包含stdio.h才能导入它们的原型.
许多编译器所做的是分析格式字符串,该格式字符串也可以在运行时提供.
以上是否有意义?