英文:
Go: Invalid memory address or nil pointer dereference when reading files and strings at same time
问题
我有以下函数waitForInput
,它监听TCP输入,连接创建后,将其分配给客户端结构体,该结构体是该函数的一个输入参数。
func waitForInput(client *util.Client) {
defer close(out)
var dstFile = ""
var fileBytes = make([]byte, 0)
reader := bufio.NewReader(client.Connection)
for {
if client.SendingOperation == "command" {
line, err := reader.ReadBytes('\n')
myString := strings.TrimSpace(string(line))
action, _, body := getAction(myString)
if action == "send" {
dstFile = body
client.SetSendingOperation("file")
}
//做一些其他的事情
} else {
fmt.Printf("IN FILE %s %s \n", client.Username, client.SendingOperation)
bytes, err := reader.ReadBytes('\n')
if err == nil {
fmt.Printf("ERROR:: ", err.Error())
}
fmt.Printf("The bytes: %s \n", bytes)
fmt.Printf("fileBytes: %s \n", fileBytes)
if err != nil {
if err == io.EOF {
writeBytesToFile(dstFile, fileBytes)
//先返回监听命令
client.SetSendingOperation("command")
fileBytes = make([]byte, 0)
}
}else {
fileBytes = append(fileBytes, bytes...)
}
}
}
}
该函数可以读取命令或文件,它们作为字节数组发送,并且如果是命令+文件,则会将它们附加在一起,例如messageBytes = append(commandBytes, fileBytes...)
。当只发送命令而不是命令+文件时,它运行正常。但是当同时发送命令和文件时,我遇到了以下错误:panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x2 addr=0x18 pc=0x1007285b0]
。奇怪的是,如果我注释掉这个if检查:if err == nil {fmt.Printf("ERROR:: ", err.Error())}
,代码会打印出fmt.Printf("The bytes: %s \n", bytes)
的结果,所以我不知道发生了什么,我已经试了几天来修复它,所以有人知道该怎么做吗?或者有人知道如何同时从客户端传递连接中的字符串和文件读取命令的替代方法吗?
英文:
I have the following function waitForInput
that listens for TCP input, after the connection has been created and that one has been assigned to the client struct which is one of the input params of that one.
func waitForInput(client *util.Client) {
defer close(out)
var dstFile = ""
var fileBytes = make([]byte, 0)
reader := bufio.NewReader(client.Connection)
for {
if client.SendingOperation == "command" {
line, err := reader.ReadBytes('\n')
myString := strings.TrimSpace(string(line))
action, _, body := getAction(myString)
if action == "send" {
dstFile = body
client.SetSendingOperation("file")
}
//Do some other stuff
} else {
fmt.Printf("IN FILE %s %s \n", client.Username, client.SendingOperation)
bytes, err := reader.ReadBytes('\n')
if err == nil {
fmt.Printf("ERROR:: ", err.Error())
}
fmt.Printf("The bytes: %s \n", bytes)
fmt.Printf("fileBytes: %s \n", fileBytes)
if err != nil {
if err == io.EOF {
writeBytesToFile(dstFile, fileBytes)
//Go back to listen commands first
client.SetSendingOperation("command")
fileBytes = make([]byte, 0)
}
}else {
fileBytes = append(fileBytes, bytes...)
}
}
}
}
That function can read either commands or files, which are sent as byte arrays appended (if it's command + file) like messageBytes = append(commandBytes, fileBytes...)
. It works fine when sending only commands and not both, commands + files. But when sending commands and files I got the following error: panic: runtime error: invalid memory address or nil pointer dereference
, The weird thing is that if I comment that if check:
[signal SIGSEGV: segmentation violation code=0x2 addr=0x18 pc=0x1007285b0]if err == nil {fmt.Printf("ERROR:: ", err.Error())}
, the code prints the bytes resulting from fmt.Printf("The bytes: %s \n", bytes)
, so I don't know whats going on, and I've been trying to fix it by days, so does anyone know what to do there, or does anyone know an alternative for reading commands as strings and files passed in a connection from a client to a server at the same time?
答案1
得分: 1
if err == nil {
fmt.Printf("ERROR:: ", err.Error())
}
这段代码会导致panic: runtime error: invalid memory address or nil pointer dereference
,因为在检查err == nil
之后,你仍然访问了err.Error()
。所以在这种情况下,nil.Error()
会抛出错误。
我建议删除上面的代码块,并修改代码中更下面的错误处理部分。
fmt.Printf("IN FILE %s %s \n", client.Username, client.SendingOperation)
bytes, err := reader.ReadBytes('\n')
// 移除这部分
// if err == nil {
// fmt.Printf("ERROR:: ", err.Error())
// }
fmt.Printf("The bytes: %s \n", bytes)
fmt.Printf("fileBytes: %s \n", fileBytes)
if err != nil {
if err == io.EOF {
writeBytesToFile(dstFile, fileBytes)
// 返回到首先监听命令
client.SetSendingOperation("command")
fileBytes = make([]byte, 0)
} else { // 添加这个 else 块
fmt.Printf("ERROR:: ", err.Error())
}
} else {
fileBytes = append(fileBytes, bytes...)
}
英文:
>
> if err == nil {
> fmt.Printf("ERROR:: ", err.Error())
> }
>
This will definitely give panic: runtime error: invalid memory address or nil pointer dereference
since you are accessing err.Error()
after you have already checked err == nil
. So in this case nil.Error()
is throwing the error.
I would suggest removing the above code code block and modify the error handling further down the code.
fmt.Printf("IN FILE %s %s \n", client.Username, client.SendingOperation)
bytes, err := reader.ReadBytes('\n')
// REMOVE THIS
// if err == nil {
// fmt.Printf("ERROR:: ", err.Error())
// }
fmt.Printf("The bytes: %s \n", bytes)
fmt.Printf("fileBytes: %s \n", fileBytes)
if err != nil {
if err == io.EOF {
writeBytesToFile(dstFile, fileBytes)
//Go back to listen commands first
client.SetSendingOperation("command")
fileBytes = make([]byte, 0)
} else { // ADD THIS ELSE BLOCK
fmt.Printf("ERROR:: ", err.Error())
}
} else {
fileBytes = append(fileBytes, bytes...)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论