c中的strcpy()给我分段错误

时间:2019-12-06 23:50:04

标签: c segmentation-fault

我正在尝试为TCP服务器中的客户端分配名称,但是strcpy()函数给我一个分段错误。

struct clients{
  int client_fd;
  char* name;
  struct clients* next;
}

struct clients* first;
first->client_fd = 1;
first->name = NULL;
memset(&first->name, 0, sizeof(first->name));
first->name = (char*)malloc(100*sizeof(char));
strcpy(first->name, "User");
first->next = NULL;

1 个答案:

答案 0 :(得分:5)

指针struct clients* first;并不指向任何malloc d内存,因此尝试像first->client_id = 1这样访问其上的属性是未初始化的指针取消引用。

由于取消引用后行为未定义,因此可能在strcpy(或其他任何地方,但strcpy不是罪魁祸首)处发生分段错误。考虑使用valgrind之类的工具在发生这些非法内存访问时对其进行识别。

  • 行:

    first->name = NULL;
    memset(&first->name, 0, sizeof(first->name));
    

    实际上并没有做任何事情,因为first->name存储位置随后被覆盖。您可以忽略这些。

  • (char*)malloc(100*sizeof(char));可以是malloc(5)sizeof(char)保证为1个字节,(char *)是不必要的强制转换,并且100对于"User"来说是太多的内存,free仅需要5个字符(一个为空终止符) 。
  • malloc分配了内存以避免泄漏。
  • 检查malloc的返回值以确保成功分配内存是一个好主意。
  • 您可以使用strdup代替strcpy / strdup对,但是这样做的缺点是您可能会忘记#include <stdio.h> #include <stdlib.h> #include <string.h> struct clients { int client_fd; char* name; struct clients* next; }; int main(void) { struct clients* first = malloc(sizeof(*first)); first->client_fd = 1; first->name = malloc(5); strcpy(first->name, "User"); first->next = NULL; printf("%d %s\n", first->client_fd, first->name); // => 1 User free(first->name); free(first); return 0; } 分配的内存需要释放。

这是一个重写:

<!--

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements. See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership. The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied. See the License for the
    specific language governing permissions and limitations
    under the License.

-->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:sec="http://www.springframework.org/schema/security"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <sec:global-method-security
            pre-post-annotations="enabled" />

    <tx:annotation-driven />

    <context:component-scan
            base-package="org.apache.fineract.accounting.*,
                                          org.apache.fineract.commands.provider,
                                          org.apache.fineract.commands.handler,
                                          org.apache.fineract.commands.service,
                                          org.apache.fineract.commands.*,
                                          org.apache.fineract.accounting.*,
                                          org.apache.fineract.infrastructure.*,
                                          org.apache.fineract.scheduledjobs.*,
                                          org.apache.fineract.organisation.*,
                                          org.apache.fineract.portfolio.loanaccount.*,
                                          org.apache.fineract.portfolio.savings.*,
                                          org.apache.fineract.portfolio.*,
                                          org.apache.fineract.useradministration.*,
                                          org.apache.fineract.mix.*,
                                          org.apache.fineract.template.*,
                                          org.apache.fineract.template.service,
                                          org.apache.fineract.batch">
        <context:exclude-filter expression="org.springframework.stereotype.Controller"
                                type="annotation" />

        <!-- We do NOT want all @Configuration "beans" to be auto-detected by ComponentScan,
             but we want to use / import them explicitly in Tests & Spring Boot applications,
             or other import in other @Configuration, so that we could have mutually exclusive ones.
         -->
        <context:exclude-filter expression="org.springframework.context.annotation.Configuration"
                                type="annotation" />
    </context:component-scan>

    <bean id="auditorAware"
          class="org.apache.fineract.infrastructure.core.domain.AuditorAwareImpl" />
    <jpa:auditing auditor-aware-ref="auditorAware" />

    <jpa:repositories base-package="org.apache.fineract.commands.domain" />
    <jpa:repositories base-package="org.apache.fineract.infrastructure.*.domain" />
    <jpa:repositories base-package="org.apache.fineract.accounting.*.domain" />
    <jpa:repositories base-package="org.apache.fineract.useradministration.domain" />
    <jpa:repositories base-package="org.apache.fineract.organisation.*.domain" />
    <jpa:repositories base-package="org.apache.fineract.portfolio.*" />
    <jpa:repositories base-package="org.apache.fineract.mix.domain" />
    <jpa:repositories base-package="org.apache.fineract.scheduledjobs.*" />
    <jpa:repositories base-package="org.apache.fineract.template.domain" />

    <import resource="infrastructure.xml" />

    <import resource="securityContext.xml" />

    <import resource="cache.xml" />

    <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
        <property name="taskExecutor">
            <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
        </property>
    </bean>

    <import resource="spmContext.xml"/>
</beans>