试图将char数组复制到struct崩溃

时间:2016-09-27 20:41:56

标签: c arrays swift struct bluetooth-lowenergy

(前言我的C很可怕)

我尝试将字符串从iOS发送到BLE设备。我在swift中对字符串进行编码并将其写为:

func sendUserName(userName: String) {
    let bytes: [UInt8] = Array(userName.utf8)

    print(bytes.count)

    let data = NSData(bytes: bytes, length: bytes.count)
    capsenseLedBoard!.writeValue(data, forCharacteristic: userIdCharacteristic, type: CBCharacteristicWriteType.WithResponse)
}

我发送此字符串"THISISATEST123456789",此行print(bytes.count)打印出20

我像这样接收BLE设备上的数据并将其传递给下面的userDidConnect函数:

userDidConnect((char *)wrReqParam->handleValPair.value.val);

我有一个名为struct的{​​{1}},如下所示:

Event

我有一个像这样声明的全局变量:

struct Event {
    char time[20];   // The time in ISO 1601 format
    char name[3];    // The two character name of the event. See header for declarations.
    char userId[20]; // The userId of the connected user if one is present.
    struct Event* next;
};

然后我有一个看起来像这样的入队函数:

char currentlyConnectedUserID[20];

我有一个接受新userId的函数,然后从中创建一个新的Event并将其添加到链接列表中......这就是它想要做的事情:

/**
 Creates a new Event and adds to the linked list.

 @param time   The time in ISO 8601 format.
 @param name   The name descriptor of the event ("VS", "VO", etc.)
 @param userId The id of the user who is currently connect (if they are connected).
 */
    void enqueueEvent(char time[20], char name[3], char userId[20]) {

    struct Event* temp = (struct Event*)malloc(sizeof(struct Event));
    strncpy( temp->time,   time, 20);
    strncpy( temp->name,   name, 3);
    strncpy( temp->userId, userId, 20);
    temp->next = NULL;

    if(front == NULL && rear == NULL) {
        front = rear = temp;
        return;
    }
    rear->next = temp;
    rear = temp;
}

目前,如果我运行上面的void userDidConnect(char *userId) { size_t destination_size = sizeof(userId); snprintf(currentlyConnectedUserID, destination_size, "%s", userId); //enqueueEvent("2007-03-01T13:00:20", "UC", currentlyConnectedUserID); showMessageInUART(currentlyConnectedUserID, sizeof(currentlyConnectedUserID)); } 方法,我就可以正确打印userDidConnect。但是,如果我取消注释这一行:

currentlyConnectedUserID

我得到了#34;崩溃"。我在一个相当模糊的IDE(赛普拉斯的PSoC Creator)中这样做,所以我没有看到任何错误日志或IDE崩溃日志。我能告诉的唯一方法是永远不会调用//enqueueEvent("2007-03-01T13:00:20", "UC", currentlyConnectedUserID); ,所以我知道它必须是那条线。

如果我这样做,我能够成功创建并加入新活动:

showMessageInUART

我唯一想到的可能是数组的大小错了?也许?或者也许有一些尾随enqueueEvent("2007-03-01T13:00:20", "UC", "1234567891234567891"); 的事情搞砸了?

建议更新:

我试过这样做:

\0

它将正确的值赋予size_t destination_size = strlen(userId) + 1; ,但是入队仍会导致崩溃。

-

我已将currentlyConnectedUserID替换为仍然导致崩溃的strcpy;(

-

尝试这一点以确保我没有溢出仍然没有工作:

strncpy

更新

我将我的队列更新为这样,因为没有断点:

sprintf(currentlyConnectedUserID, "%.19s", userId);

这一行崩溃了:

void enqueueEvent(char time[20], char name[3], char userId[20]) { UART_UartPutString("start enqueue"); struct Event* temp = (struct Event*)malloc(sizeof(struct Event)); UART_UartPutString("1"); strncpy( temp->time, time, 20); UART_UartPutString("2"); strncpy( temp->name, name, 3); UART_UartPutString("3"); strncpy( temp->userId, userId, 20); UART_UartPutString("4"); temp->next = NULL; UART_UartPutString("5"); if(front == NULL && rear == NULL) { front = rear = temp; return; } rear->next = temp; rear = temp; }

我们从来没有在这里做过:strncpy( temp->time, time, 20);

如果我从UART_UartPutString("2");调用此功能,则可以正常工作。知道为什么当从不同的方法调用时它会崩溃吗?

1 个答案:

答案 0 :(得分:1)

strcpy功能将源指向的C字符串复制到目标指向的数组中,包括终止空字符(并在此处停止)。 因此,我建议您使用enqueueEvent而非危险strncpy更改strcpy功能:

void enqueueEvent(char time[20], char name[3], char userId[20]) {

    struct Event* temp = (struct Event*)malloc(sizeof(struct Event));
    strncpy( temp->time,   time,20);
    strncpy( temp->name,   name,3);
    strncpy( temp->userId, userId,20);
    temp->next = NULL;

    if(front == NULL && rear == NULL) {
        front = rear = temp;
        return;
    }
    rear->next = temp;
    rear = temp;
}

还将temp指针从enqueueEvent函数的本地堆栈的分配更改为全局级别,因为当超出函数时指针分配就消失了。