微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过字符指针和strcpy了解malloc

如何解决通过字符指针和strcpy了解malloc

我想编写一个简单的程序,但我想让它无法理解strcpy和适当的内存管理,但是它仍然可以执行。我正在尝试为一个字符串动态分配内存(使用malloc),足以仅将3个(或小于源的任何字符)字符用作目标,并比源的字符串数组分配的内存(或字符)少在堆栈上分配(10个字符的字符串)。无论我如何定义内存分配,它都会复制并打印内容。这是怎么了?

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

int main()
{
    char *ch = NULL;
    char name[10] = "something";
    ch = (char*)malloc(3 * sizeof(char));
    strcpy(ch,name);
    
    printf("%s\n",name);
    free(ch);
    ch = NULL;
}

解决方法

这里的错误是您依靠undefined behaviour

对于越界(或无效)的内存访问,编译器不会引发任何错误,但是当您的程序尝试访问无效的内存时,行为是不确定的。

对于strcpy(),如果目标缓冲区的大小不足以容纳源中的内容(包括空终止符),那么实际上您将超出范围访问内存,这是无效的,从而导致未定义的行为。程序员有责任确保目标缓冲区有足够的空间来存储要复制的字符串。

man page

strcpy()函数将src指向的字符串(包括终止空字节('\0')复制到dest指向的缓冲区。这些字符串可能不会重叠,并且目标字符串dest必须足够大才能接收副本。[....]

,

写数组超出范围的行为是不确定的。在我的计算机上,未经优化:

subdirectory1

并启用优化

    ///change example.com with your own domain or relative path.
    function createCookie(name,value,days) {
      if (days) {
        var date = new Date();
        date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
        var expires = "; expires=" + date.toGMTString();
      } else var expires = "";
      document.cookie =
        name + "=" + value + expires + "; path=/; domain=.example.com";
    }
    
    function readCookie(name) {
      var nameEQ = name + "=";
      var ca = document.cookie.split(";");
      for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == " ") c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
      }
      return undefined;
    }
    
    
    async function setAuthFromCookie() {
      caches.open("auth").then(function (cache) {
        console.log("Set Cookie");
        return cache.add(["https://example.com/cacheAuth.php"]);
      });
    }
    async function setAuthToCookie() {
      var uid = readCookie("uid");
      var authKey = readCookie("authKey");
      caches.open("auth").then((cache) => {
        cache
          .match("https://example.com/cacheAuth.php",{
            ignoreSearch: true,})
          .then((response) => response.json())
          .then((body) => {
            if (body.uid && uid == "undefined") {
              /// and if cookie is empty
              console.log(body.authKey);
              createCookie("authKey",body.authKey,3000);
            }
          })
          .catch((err) => {
            console.log("Not cached yet");
          });
      });
    }

    setTimeout(() => {
      setAuthFromCookie();
      //this is for setting cookie from server
    },1000);

    setAuthToCookie();

原因是使用 优化功能的GCC实际上会传播数组大小,并产生等同于

的机器代码
% gcc overflow.c
% ./a.out    
something

Check this image 检查目标缓冲区的长度,由于超出了目标缓冲区的长度,程序将在运行时中止

始终在开发时,请记住测试您的代码也启用了优化

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。