所以我在C中发现了this关于套接字的惊人教程。到目前为止,这一切都很有意义,但我很好奇我看到了用指针和没有指针的结构。当你应该或不应该使用指针结构时,我感到很困惑。
我在教程中找到了这个例子:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_LENGTH 2000
int main(int argc, char *argv[]) {
int socket_desc;
struct sockaddr_in server;
char *message, server_reply[MAX_LENGTH];
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket :(");
}
server.sin_addr.s_addr = inet_addr("173.194.121.2");
server.sin_family = AF_INET;
server.sin_port = htons(80);
if (connect(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
puts("Connection error.");
return 1;
}
puts("Connected!\n");
close(socket_desc);
return 0;
}
所以我决定将服务器变量转换为指针,看看发生了什么。这就是我想出的:
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_LENGTH 2000
int main(int argc, char *argv[]) {
int socket_desc;
struct sockaddr_in *server;
char *message, server_reply[MAX_LENGTH];
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket :(");
}
server->sin_addr.s_addr = inet_addr("173.194.121.2");
server->sin_family = AF_INET;
server->sin_port = htons(80);
if (connect(socket_desc, (struct sockaddr *)server, sizeof(*server)) < 0) {
puts("Connection error.");
return 1;
}
puts("Connected!\n");
close(socket_desc);
return 0;
}
这也编译得很好,但是当我运行它时给了我Segmentation fault: 11
。
所以我的问题是为什么这段代码不起作用,我怎么知道何时需要指向结构或普通结构的指针。谢谢!
答案 0 :(得分:4)
在第一个版本中,您声明了一个完整的结构,这意味着结构的内存放在堆栈上。
在第二个版本中,您声明了一个指向struct的指针,但是没有为它分配内存,因此当您尝试寻址结构中不存在的成员时,就会出现段错误。
如果更改第二个以为结构分配内存:
struct sockaddr_in *server = malloc(sizeof(struct sockaddr_in));
然后在退出之前记住free(server);
,你将正确处理内存。
要回答问题的第二部分,如果您需要将数据(在本例中为连接信息)存储在某些其他数据结构中以跟踪它,您可能只需要指向结构的指针,或者如果由于某种原因需要将其传递给另一个例程。
但是,对于后一种情况,使用&
运算符来获取地址,堆栈上的结构用作传递给例程的指针,通常在connect()
调用中完成在第一个例程中,它使用此参数执行此操作:(struct sockaddr *)&server
答案 1 :(得分:0)
服务器是一个指针。它指向什么?你没说。服务器可以指向struct sock_addr_in,但它没有。
它就像一辆在路上开得很好的汽车,但是你试图在路标上行驶。
答案 2 :(得分:0)
如果要传递指针的API打算取消引用该指针,则代表您在其中存储值,您需要将其传递给有效的内存位置,以便存储操作成功。
如果您传递指针的API只想将其传递给您(例如通过回调函数),那么指针值可以是当您获得值时对您有意义的任何值。 / p>