【问题标题】:Beginner in C: strings and memoryC 初学者:字符串和内存
【发布时间】:2015-08-18 16:10:24
【问题描述】:

所以我正在做的这门课程希望我们玩弄内存管理和指针。我并没有完全理解它们。

我不断收到错误:

分段错误(核心转储)

显然我无法访问内存?

我的slen 函数有问题吗?

/*

In these exercises, you will need to write a series of C functions. Where possible, these functions should be reusable (not use global variables or fixed sized buffers) and robust (they should not behave badly under bad input eg empty, null pointers) .
As well as writing the functions themselves, you must write small programs to test those functions.

- Remember, in C, strings are sequences of characters stored in arrays AND the character sequence is delimited with '\0' (character value 0).

----------------------------------------------------

1) int slen(const char* str)
    which returns the length of string str [slen must not call strlen - directly or indirectly]
*/

#include <stdio.h>
#include <stdlib.h>

/* Returns the length of a given string */
int slen(const char* str) {
    int size = 0;
    while(str[size] != '\0') {
        size++;
    }
    return size;
}

/*
2) char* copystring(const char* str)
    which returns a copy of the string str. [copystring must not call any variant of strcpy or strdup - directly or indirectly]*/
char* copystring(const char* str) {
    int size = slen(str);
    char *copy = (char*) malloc (sizeof(char) * (size + 1));
    copy[size] = '\0';
    printf("before loop");
    int i = 0;
    while (*str != '0') {
        copy[i++] = *str++;
    }
    return copy;
}


int main() {
    char *msg = NULL;
    printf("Enter a string: ");
    scanf("%s", &msg);
    int size = slen(msg);
    //printf("The length of this message is %d.", size);
//  printf("Duplicate is %s.", copystring(msg));

    // Reading from file


}

【问题讨论】:

  • 这里至少有一个提示:当您将 msg 交给 scanf 时,您希望它指向什么?
  • 在 C 中,当调用 malloc() 和函数族时。返回值为 void*。 void 指针可以分配给任何其他指针,因此不要强制转换返回值。表达式 'sizeof(char)' 定义为 1,因此对传递给 malloc() 的参数没有影响。建议通过删除强制转换和删除“sizeof(char)”表达式来整理代码。
  • 关于这一行:'char *msg = NULL;' 'msg' 指向地址 0,不允许用户程序访问/写入。建议使用“readline()”或其他方法让“msg”指向内存中的某个值位置。

标签: c memory string


【解决方案1】:

问题不在于您的 slen 函数,它发生在您使用 scanf 之前:

  • 您需要为使用scanf 从用户那里读取的字符串留出一些空间
  • 您无需将内存缓冲区的地址传递给scanf,该变量已经保存了一个地址。

修改代码:

char msg[101];
printf("Enter a string: ");
scanf("%s", msg);
int size = slen(msg);

或者,如果您被要求了解内存分配,请研究malloc 的用法:

char *msg = malloc(101);
printf("Enter a string: ");
scanf("%s", msg);
int size = slen(msg);

在学习malloc的同时,别忘了也学习一下free的相关用法。

这里同样重要和重要的是缓冲区大小的管理:当您为要从用户扫描的字符串创建内存时,您应该限制实际读取的字符串数量 。有几种方法可以做到这一点:首先研究scanf 格式字符串,您可以在其中使用:

scanf("%100s", msg);

【讨论】:

  • 当我们在这里时,scanf("%100s", msg) 会更好,因为它可以避免任何缓冲区溢出...
  • @SergeBallesta 当然,但我认为缓冲区大小限制处理可能超出了本课的范围
  • 恕我直言,初学者永远不会过早学会保护自己免受缓冲区溢出的影响,也永远不会对它们过于谨慎:-)
  • @SergeBallesta 当然,我认为这里的 cmets 是有用且温和的介绍。但我会在答案中添加一个简介。
【解决方案2】:

您需要在main 中为msg 分配内存 使用char msg[10] 或使用malloc。 char *msg = malloc(10*sizeof(char))

【讨论】:

  • 不是 (10 * sizeof(char)) == 10 ?
  • 只是为了让 OP 明白,分配 10 个字符数组将是 10,将内存分配给 10 个整数的数组,10*sizeof(int)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多